有没有办法在 C# 代码中获取当前源文件名和行号,并将该值打印在控制台输出中?就像 C 语言中的 LINE 和 FILE 一样?
请给予指导。
非常感谢!
有没有办法在 C# 代码中获取当前源文件名和行号,并将该值打印在控制台输出中?就像 C 语言中的 LINE 和 FILE 一样?
请给予指导。
非常感谢!
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!");
输出:
Program.cs_Main(11): .NET很棒!
这里发生了什么事情?
你定义了一个带有可选
参数的方法,并使用特殊属性进行装饰。如果您调用方法而没有传递实际参数(保留默认值)-框架将为您填充它们。
CallerMemberName
很棒,但缺少 CallerTypeName
属性既令人困惑又让人恼火。 - Dai这个答案已经过时了!请参考@taras的答案获取更近期的信息。
没有常量 :(
你能做的只有一个更丑陋的选择:
string currentFile = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();
int currentLine = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber();
仅在有PDB文件可用时起作用。
您可以使用System.Diagnostics命名空间中的StackTrace对象,但是只有在存在PDB文件时才能获得信息。
PDB文件默认情况下会为Debug和Release版本生成,唯一的区别是Debug版本设置为生成完整的调试信息,而Release版本设置为仅生成pdb(完整/pdb-only)。
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主题中阅读有关在DEBUG vs. RELEASE构建中使用#if预处理器的信息。
C# if/then directives for debug vs release
编辑:如果您仍需要在发布版本中进行调试,请阅读Stackoverflow上的以下答案:
Display lines number in Stack Trace for .NET assembly in Release mode
System.Diagnostics.Debug.Print(this.GetType().ToString() + " My Message");
如果你想写自己的Debug.Assert版本,那么这里是一个更完整的答案:
// 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!");
}
}