Как получить текущий номер строки?

Вот пример того, что я хочу сделать:

 MessageBox.Show("Error line number "+CurrentLineNumber);

Текущий номер строки будет номером строки в исходном коде этого фрагмента кода.

Как я могу это сделать?

Ответ 1

В .NET 4.5/С# 5 вы можете заставить компилятор выполнить эту работу для вас, написав метод утилиты, который использует новые атрибуты вызывающего абонента:

static void SomeMethodSomewhere()
{
    ShowMessage("Boo");
}
...
static void ShowMessage(string message,
    [CallerLineNumber] int lineNumber = 0,
    [CallerMemberName] string caller = null)
{
     MessageBox.Show(message + " at line " + lineNumber + " (" + caller + ")");
}

Это отобразится, например:

Boo в строке 39 (SomeMethodSomeewhere)

Там также [CallerFilePath], который сообщает вам путь к исходному кодовому файлу.

Ответ 2

Используйте метод StackFrame.GetFileLineNumber, например:

private static void ReportError(string message)
{
     StackFrame callStack = new StackFrame(1, true);
     MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName() 
          + ", Line: " + callStack.GetFileLineNumber());
}

См. Запись в блоге Scott Hanselman для получения дополнительной информации.

[Редактировать: Добавлено следующее]

Для тех, кто использует .Net 4.5 или более позднюю версию, рассмотрите атрибуты CallerFilePath, CallerMethodName и CallerLineNumber в пространстве имен System.Runtime.CompilerServices. Например:

public void TraceMessage(string message,
        [CallerMemberName] string callingMethod = "",
        [CallerFilePath] string callingFilePath = "",
        [CallerLineNumber] int callingFileLineNumber = 0)
{
    // Write out message
}

Аргументы должны быть string для CallerMemberName и CallerFilePath и int для CallerLineNumber и должны иметь значение по умолчанию. Указание этих атрибутов в параметрах метода указывает компилятору вставлять соответствующее значение в вызывающий код во время компиляции, что означает, что он работает через запутывание. Посмотрите Информацию о вызывающем абоненте для получения дополнительной информации.

Ответ 3

Я предпочитаю один вкладыш так:

int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();

Ответ 4

Для тех, кто нуждается в решении .NET 4.0+:

using System;
using System.IO;
using System.Diagnostics;

public static void Log(string message) {
   StackFrame stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1);
   string fileName = stackFrame.GetFileName();
   string methodName = stackFrame.GetMethod().ToString();
   int lineNumber = stackFrame.GetFileLineNumber();

   Console.WriteLine("{0}({1}:{2})\n{3}", methodName, Path.GetFileName(fileName), lineNumber, message);
}

Как позвонить:

void Test() {
   Log("Look here!");
}

Вывод:

Void Test() (FILENAME.cs: 104)

Посмотрите здесь!

Измените формат Console.WriteLine, как вам нравится!

Ответ 5

Если это в блоке catch try, используйте это.

try
{
    //Do something
}
catch (Exception ex)
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
    Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}

Ответ 6

В .NET 4.5 вы можете получить номер строки, создав функцию:

static int LineNumber([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
    return lineNumber; 
}

Затем каждый раз, когда вы вызываете LineNumber(), вы будете иметь текущую строку. Это имеет преимущество перед любым решением, используя StackTrace, что он должен работать как в отладке, так и в выпуске.

Итак, беря исходный запрос того, что требуется, он станет следующим:

MessageBox.Show("Error enter code here line number " + LineNumber());

Это строится на превосходном ответе Марка Гравелла.

Ответ 7

Это работает для меня:

try
{
 //your code;
}
catch(Exception ex)
{
  MessageBox.Show(ex.StackTrace + " ---This is your line number, bro' :)", ex.Message);
}