Aqui está um exemplo do que eu quero fazer:
MessageBox.Show("Error line number " + CurrentLineNumber);
No código acima de CurrentLineNumber
, deve estar o número da linha no código-fonte deste trecho de código.
Como eu posso fazer isso?
Aqui está um exemplo do que eu quero fazer:
MessageBox.Show("Error line number " + CurrentLineNumber);
No código acima de CurrentLineNumber
, deve estar o número da linha no código-fonte deste trecho de código.
Como eu posso fazer isso?
Respostas:
No .NET 4.5 / C # 5, você pode fazer com que o compilador faça esse trabalho para você, escrevendo um método utilitário que usa os novos atributos do chamador:
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 + ")");
}
Isso exibirá, por exemplo:
Boo na linha 39 (SomeMethodSomewhere)
Também há o [CallerFilePath]
que informa o caminho do arquivo de código original.
Use o método StackFrame.GetFileLineNumber , por exemplo:
private static void ReportError(string message)
{
StackFrame callStack = new StackFrame(1, true);
MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName()
+ ", Line: " + callStack.GetFileLineNumber());
}
Consulte a entrada do blog de Scott Hanselman para obter mais informações.
[Editar: adicionado o seguinte]
Para aqueles que usam .Net 4.5 ou posterior, considere CallerFilePath , CallerMethodName e CallerLineNumber no namespace System.Runtime.CompilerServices. Por exemplo:
public void TraceMessage(string message,
[CallerMemberName] string callingMethod = "",
[CallerFilePath] string callingFilePath = "",
[CallerLineNumber] int callingFileLineNumber = 0)
{
// Write out message
}
Os argumentos devem ser string
para CallerMemberName
e CallerFilePath
e um int
para CallerLineNumber
e devem ter um valor padrão. Especificar esses atributos em parâmetros de método instrui o compilador a inserir o valor apropriado no código de chamada em tempo de compilação, o que significa que funciona por meio de ofuscação. Consulte Informações do chamador para obter mais informações.
StackFrame
exemplo no Mono , certifique-se de usar--debug
em tempo de compilação e em tempo de execução
StackFrame
não está disponível no .NET Core. Use a resposta de Marc Gravell.
= string.Empty
gera um erro "O valor do parâmetro padrão para 'callingFilePath' deve ser uma constante de tempo de compilação" !
""
) em vez de string.Empty
.
Eu prefiro um liners, então:
int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();
Para aqueles que precisam de uma solução de método .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);
}
Como ligar:
void Test() {
Log("Look here!");
}
Resultado:
Teste de Vazio () (FILENAME.cs: 104)
Olhe aqui!
Altere o formato Console.WriteLine como quiser!
System.Diagnostics.Debug.WriteLine(String.Format("{0}({1}): {2}: {3}", fileName, lineNumber, methodName, message));
então você pode clicar na linha na janela de saída e ser levado para essa linha na fonte.
Se estiver em um bloco try catch, use-o.
try
{
//Do something
}
catch (Exception ex)
{
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}
No .NET 4.5, você pode obter o número da linha criando a função:
static int LineNumber([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
return lineNumber;
}
Então, cada vez que você ligar, LineNumber()
você terá a linha atual. Isso tem a vantagem sobre qualquer solução que usa o StackTrace de que deve funcionar tanto na depuração quanto na liberação.
Então, pegando a solicitação original do que é necessário, ele se tornaria:
MessageBox.Show("Error enter code here line number " + LineNumber());
Isso se baseia na excelente resposta de Marc Gravell.