用于记录目的
__LINE__
__FILE__
Run Code Online (Sandbox Code Playgroud)
我是C/C++的朋友.在Java中获取该信息,我不得不抛出异常并抓住它.为什么在现代编程语言中忽略了这些旧的备用语言?他们的简约有些神奇.
rok*_*ken 73
调用者信息已添加到.NET 4.5中.这将被编译,这是一个必须手动检查堆栈跟踪的重大改进.
public void Log(string message,
[CallerFilePath] string filePath = "",
[CallerLineNumber] int lineNumber = 0)
{
// Do logging
}
Run Code Online (Sandbox Code Playgroud)
只需以这种方式调用它,编译器就会为您填写文件名和行号:
logger.Log("Hello!");
Run Code Online (Sandbox Code Playgroud)
Ed *_* S. 28
这很丑陋,但您可以使用StackTrace和StackFrame类在C#中执行以下操作:
StackTrace st = new StackTrace(new StackFrame(true));
Console.WriteLine(" Stack trace for current level: {0}", st.ToString());
StackFrame sf = st.GetFrame(0);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Method: {0}", sf.GetMethod().Name);
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
Run Code Online (Sandbox Code Playgroud)
当然,这带来了一些开销.
Dan*_*ker 11
与此最接近的是,您可以创建一个StackTrace对象并在堆栈顶部找出方法的名称,这样您就可以接近__FUNCTION__宏的功能.
StackTrace stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames();
foreach (StackFrame stackFrame in stackFrames)
Console.WriteLine(stackFrame.GetMethod().Name);
Run Code Online (Sandbox Code Playgroud)
为了降低手动输入的成本以及运行时代码,您可以编写一个辅助方法:
[Conditional("Debug")]
public void LogMethodName()
{
Trace.WriteLine("Entering:" + new StackTrace().GetFrame(1).GetMethod().Name);
}
Run Code Online (Sandbox Code Playgroud)
注意我们如何获得第1帧,因为第0帧LogMethodName本身就是.通过将其标记为条件("调试"),我们确保从发布版本中删除代码,这是避免可能不需要的运行时成本的一种方法.
随着来电信息(在.NET 4.5中引入),您可以创建相当于__LINE__与__FILE__在C#中:
static int __LINE__([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
return lineNumber;
}
static string __FILE__([System.Runtime.CompilerServices.CallerFilePath] string fileName = "")
{
return fileName;
}
Run Code Online (Sandbox Code Playgroud)
唯一要记住的是,这些是函数,而不是编译器指令。
因此,例如:
MessageBox.Show("Line " + __LINE__() + " in " + __FILE__());
Run Code Online (Sandbox Code Playgroud)
如果您要在实践中使用此名称,那么我建议使用其他名称。我使用C / C ++名称只是为了更清楚它们返回的内容,诸如CurrentLineNumber()和CurrentFileName()可能是更好的名称。
与任何使用的解决方案相比,使用呼叫者信息的优势StackTrace在于,行和文件信息可用于调试和发布。