Вот пример того, что я хочу сделать:
MessageBox.Show("Error line number " + CurrentLineNumber);
В коде выше CurrentLineNumber
должен быть номер строки в исходном коде этого фрагмента кода.
Как я могу это сделать?
Вот пример того, что я хочу сделать:
MessageBox.Show("Error line number " + CurrentLineNumber);
В коде выше CurrentLineNumber
должен быть номер строки в исходном коде этого фрагмента кода.
Как я могу это сделать?
Ответы:
В .NET 4.5 / C # 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 + ")");
}
Это отобразит, например:
Бу в строке 39 (SomeMethodSomewhere)
Там также [CallerFilePath]
указывается путь к исходному файлу кода.
Используйте метод StackFrame.GetFileLineNumber , например:
private static void ReportError(string message)
{
StackFrame callStack = new StackFrame(1, true);
MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName()
+ ", Line: " + callStack.GetFileLineNumber());
}
См . Запись в блоге Скотта Хансельмана для получения дополнительной информации.
[Изменить: добавлено следующее]
Для тех, кто использует .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
и должны иметь значение по умолчанию. Указание этих атрибутов в параметрах метода инструктирует компилятор вставить соответствующее значение в вызывающий код во время компиляции, что означает, что он работает через обфускацию. См. Информацию о вызывающем абоненте для получения дополнительной информации.
StackFrame
пример на Mono , обязательно используйте--debug
во время компиляции и во время выполнения
StackFrame
недоступен в .NET Core. Воспользуйтесь ответом Марка Гравелла.
= string.Empty
вызывает ошибку «Значение параметра по умолчанию для 'CallingFilePath' должно быть константой времени компиляции» !
""
) вместо string.Empty
.
Я предпочитаю одинарные вкладыши:
int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();
Для тех, кому нужно решение метода .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!");
}
Вывод:
Тест на пустоту () (FILENAME.cs: 104)
Смотри сюда!
Измените формат Console.WriteLine на свой вкус!
System.Diagnostics.Debug.WriteLine(String.Format("{0}({1}): {2}: {3}", fileName, lineNumber, methodName, message));
то вы можете щелкнуть строку в окне вывода и перейти к этой строке в источнике.
Если он находится в блоке try catch, используйте это.
try
{
//Do something
}
catch (Exception ex)
{
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}
В .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());
Это основано на прекрасном ответе Марка Гравелла.