用C#打印源文件名和行号

本文关键字:文件名 源文件 打印 | 更新日期: 2023-09-27 17:59:12

有没有办法在C#代码中检索当前源文件名和行号,并在控制台输出中打印该值?类似于C中的LINEFILE

请告知。

非常感谢

用C#打印源文件名和行号

Anders Hejlsberg在BUILD主题演讲中介绍了新的API:

打印当前文件名方法名称行号

private static void Log(string text,
                        [CallerFilePath] string file = "",
                        [CallerMemberName] string member = "",
                        [CallerLineNumber] int line = 0)
{
    Console.WriteLine("{0}_{1}({2}): {3}", Path.GetFileName(file), member, line, text);
}

测试:

Log(".NET rocks!");

输出:

程序.cs_Main(11):.NET太棒了!

这里发生了什么

使用optional参数定义方法,并使用特殊属性装饰它们。若您在不传递实际参数(保留默认值)的情况下调用方法,则Framework会为您填充这些参数。

这个答案已经过时了!查看@taras的回答,了解更多最新信息


无常数:(

你能做的要丑陋得多:

string currentFile = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName(); 
int currentLine = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(); 

仅当PDB文件可用时才起作用。

您可以使用系统中的StackTrace对象。Diagnostics命名空间,但只有当PDB文件存在时,信息才可用。

默认情况下,为Debug和Release构建生成PDB文件,唯一的区别是Debug被设置为生成完整的调试信息,而Release构建被设置为仅生成PDB(仅限full/PDB)。

Console.WriteLine(new StackTrace(true).GetFrame(0).GetFileName());
Console.WriteLine(new StackTrace(true).GetFrame(0).GetFileLineNumber());

到目前为止,还没有为此定义常量。

。NET的方法是使用StackTrace类。

然而,它仅适用于调试构建。因此,如果你使用它,你可以在之间使用StackTrace

#if DEBUG
    //your StackTrace code here
#endif

您可以在下面的Stackoverflow线程中阅读有关使用#if预处理器进行DEBUG与RELEASE构建的信息。

调试与发布的C#if/then指令

编辑:如果您在版本构建中仍然需要此调试信息,请阅读Stackoverflow上的以下答案:

在的堆栈跟踪中显示行号。NET程序集处于发布模式

如果你想要更多的内部细节,但你并不特别需要文件名和行号,你可以这样做:

System.Diagnostics.Debug.Print(this.GetType().ToString() + " My Message");

这比打印文件名有一个优势,因为如果你把它放在父类中,它会打印出实际运行代码的子类名。

如果您想编写自己版本的Debug。断言,那么这里有一个更完整的答案:

// CC0, Public Domain
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System;
public static class Logger {
    [Conditional("DEBUG")]  
    public static void Assert(bool condition, string msg,
            [CallerFilePath] string file = "",
            [CallerMemberName] string member = "",
            [CallerLineNumber] int line = 0
            )
    {
        // Debug.Assert opens a msg box and Trace only appears in
        // a debugger, so implement our own.
        if (!condition)
        {
            // Roughly follow style of C# error messages:
            // > ideone.cs(14,11): error CS1585: Member modifier 'static' must precede the member type and name
            Console.WriteLine($"{file}({line}): assert: in {member}: {msg}");
            // Or more precisely match style with a fake error so error-parsing tools will detect it:
            // Console.WriteLine($"{file}({line}): warning CS0: {msg}");
        }
    }
}
class Program {
    static void Main(string[] args) {
        Logger.Assert(1+1 == 4, "Why not!");
    }
}

在线试用。