Oto przykład tego, co chcę zrobić:
MessageBox.Show("Error line number " + CurrentLineNumber);
W powyższym kodzie CurrentLineNumber
, powinno być numerem linii w kodzie źródłowym tego fragmentu kodu.
Jak mogę to zrobić?
Oto przykład tego, co chcę zrobić:
MessageBox.Show("Error line number " + CurrentLineNumber);
W powyższym kodzie CurrentLineNumber
, powinno być numerem linii w kodzie źródłowym tego fragmentu kodu.
Jak mogę to zrobić?
Odpowiedzi:
W .NET 4.5 / C # 5 możesz sprawić, by kompilator wykonał tę pracę za Ciebie, pisząc metodę narzędzia, która używa nowych atrybutów obiektu wywołującego:
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 + ")");
}
Spowoduje to wyświetlenie na przykład:
Boo w linii 39 (SomeMethodSomewhere)
Jest tam również, [CallerFilePath]
który podaje ścieżkę do oryginalnego pliku kodu.
Użyj metody StackFrame.GetFileLineNumber , na przykład:
private static void ReportError(string message)
{
StackFrame callStack = new StackFrame(1, true);
MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName()
+ ", Line: " + callStack.GetFileLineNumber());
}
Zobacz wpis na blogu Scotta Hanselmana na aby uzyskać więcej informacji.
[Edycja: dodano następujące]
W przypadku użytkowników korzystających z .Net 4.5 lub nowszego należy rozważyć atrybuty CallerFilePath , CallerMethodName i CallerLineNumber w przestrzeni nazw System.Runtime.CompilerServices. Na przykład:
public void TraceMessage(string message,
[CallerMemberName] string callingMethod = "",
[CallerFilePath] string callingFilePath = "",
[CallerLineNumber] int callingFileLineNumber = 0)
{
// Write out message
}
Argumentami muszą być argumenty string
for CallerMemberName
i CallerFilePath
oraz int
for CallerLineNumber
i muszą mieć wartość domyślną. Określenie tych atrybutów w parametrach metody instruuje kompilator, aby wstawił odpowiednią wartość do kodu wywołującego w czasie kompilacji, co oznacza, że działa on przez zaciemnianie. Aby uzyskać więcej informacji, zobacz Informacje o dzwoniącym .
StackFrame
przykład na Mono , pamiętaj, aby używać go--debug
w czasie kompilacji iw czasie wykonywania
StackFrame
nie jest dostępny w .NET Core. Skorzystaj z odpowiedzi Marca Gravella.
= string.Empty
generuje błąd „Domyślna wartość parametru dla„ CallFilePath ”musi być stałą czasu kompilacji” !
""
) zamiast string.Empty
.
Wolę jeden wkład, więc:
int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();
Dla tych, którzy potrzebują rozwiązania metody .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);
}
Jak zadzwonić:
void Test() {
Log("Look here!");
}
Wynik:
Void Test () (FILENAME.cs: 104)
Popatrz tutaj!
Zmień format Console.WriteLine, jak chcesz!
System.Diagnostics.Debug.WriteLine(String.Format("{0}({1}): {2}: {3}", fileName, lineNumber, methodName, message));
możesz kliknąć linię w oknie wyjściowym i przejść do tej linii w źródle.
Jeśli jest w bloku try catch, użyj tego.
try
{
//Do something
}
catch (Exception ex)
{
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}
W .NET 4.5 możesz uzyskać numer linii, tworząc funkcję:
static int LineNumber([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
return lineNumber;
}
Wtedy za każdym razem, gdy zadzwonisz LineNumber()
, będziesz mieć bieżącą linię. Ma to tę przewagę nad jakimkolwiek rozwiązaniem używającym StackTrace, że powinno działać zarówno w debugowaniu, jak i wydaniu.
Biorąc więc pierwotną prośbę o to, co jest wymagane, stałoby się:
MessageBox.Show("Error enter code here line number " + LineNumber());
Opiera się to na doskonałej odpowiedzi Marca Gravella.