如何在Console.WriteLine输出中包含行号和文件名?

5

有没有一种方法可以在C#的Console.WriteLine函数中包含行号和文件名?

例如,在文件“myClass.cs”的第115行,我有以下语句:

Console.WriteLine("Hello world");

I would like the output to be:

[myClass.cs][115]:  Hello world 

1
你真的想要这样的输出吗? - Satpal
3
请看这里:https://dev59.com/smw15IYBdhLWcg3w1vOB。 - Christian Phillips
你想要修改Console.WriteLine的行为来实现这个功能,还是只是想获取行号?如果是获取行号,请查看:http://stackoverflow.com/questions/4900744/is-there-a-way-to-get-the-current-line-number-when-executing-code-c-sharp - cvbarros
3个回答

19
如果您使用的是C# 5,您可以使用调用者信息属性来实现此功能。例如:
using System;
using System.IO;
using System.Runtime.CompilerServices;

public class Test
{
    static void Log(string message,
                    [CallerFilePath] string file = null,
                    [CallerLineNumber] int line = 0)
    {
        Console.WriteLine("{0} ({1}): {2}", Path.GetFileName(file), line, message);
    }

    static void Main()
    {
        Log("Hello, world");
        Log("This is the next line");
    }
}

输出:

Test.cs (16): Hello, world
Test.cs (17): This is the next line

在C# 5之前,你只能使用执行时堆栈检查,这种检查由于内联而不太可靠,并且依赖于在执行时存在信息。(例如,在发布版本中可能不存在该信息,而上述方法仍然有效。)

2
+1 这是一个非常巧妙的技巧。 - rae1
2
需要注意的是,这些属性的重活都是由编译器来完成的。如果你使用的是 C# 5 编译器,即使针对之前的框架版本(或者没有这些版本),你也可以拥有这些属性的优美。例如,你可能正在为可移植框架创建一个 MVVM 项目,并想要使用 CallerMemberNameAttribute,但它在那个版本的 System.Runtime.CompilerServices 中不存在。如果你手动创建该属性并使用它,编译器仍然会尊重并实现它。 - Erik

0
您可以使用 这个构造函数 检查 StackTrace,从中获取一个 StackFrame,然后在 StackFrame 上调用 GetFileName()GetFileLineNumber()。请注意,这将需要应用程序中可用的 .pdb 文件。

http://social.msdn.microsoft.com/Forums/en-US/a58dc2a0-0612-407b-8cbe-10f1784ba85a/how-to-retreive-the-line-number-and-file-name-of-c-source-code?forum=csharplanguage

来自链接的修改后的代码:

using System.Diagnostics;

var StackTrace = new System.Diagnostics.StackTrace(true);
var StackFrame = StackTrace.GetFrame(0);
string FileName = StackFrame.GetFileName();
string LineNumber = StackFrame.GetFileLineNumber().ToString();

0
我会为此创建一个辅助方法,并利用Marc Gravell在这篇文章中写的解决方案: 如何获取当前行号? 类似于以下内容...
public static class WriteLineHelper
{
    public static void WriteLine(string message,
        [CallerLineNumber] int lineNumber = 0,
        [CallerMemberName] string caller = null)
    {
        Console.WriteLine(string.Format("[{0}][{1}] : {2}, caller, lineNumber, message);
    }
}

然后在 myClass.cs 中,只需将对 Console.WriteLine 的调用替换为:

WriteLineHelper.WriteLine("Hello world.");

2
......或者基本上就是Jon Skeet所说的。 - ScottMB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接