C#中是否存在与__LINE__和__FILE__相当的等价物?

8 浏览
0 Comments

C#中是否存在与__LINE__和__FILE__相当的等价物?

出于日志记录的目的,__LINE____FILE__在C/C++中是我的好朋友。在Java中,为了获得这些信息,我不得不抛出异常并捕获它。为什么这些古老的老朋友在现代编程语言中如此被忽视?它们的简洁性有一种神奇之处。

0
0 Comments

在C#中,没有直接等价于C++中的`__LINE__`和`__FILE__`的编译器指令。但是,通过使用.NET 4.5引入的`Caller Information`特性,可以创建类似的功能。

在C#中,可以通过以下方式创建`__LINE__`等价物:

static int __LINE__([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
    return lineNumber;
}
static string __FILE__([System.Runtime.CompilerServices.CallerFilePath] string fileName = "")
{
    return fileName;
}

需要注意的是,这些不是编译器指令,而是函数。

例如,可以这样使用:

MessageBox.Show("Line " + __LINE__() + " in " + __FILE__());

如果要在实践中使用这种方法,建议使用不同的名称。上述示例中使用了C/C++的名称,只是为了清楚起见。更好的命名可能是`CurrentLineNumber()`和`CurrentFileName()`。

与使用`StackTrace`的任何解决方案相比,使用`Caller Information`的优势在于行号和文件信息在调试和发布模式下都可用。

0
0 Comments

在C#中,是否存在类似于C语言中的`__LINE__`和`__FILE__`的等价物?这个问题的出现是因为为了在C#中获取当前代码的行号和文件名,需要使用`StackTrace`和`StackFrame`类。以下是一个示例代码:

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());

当然,使用这种方法会增加一些额外的开销。因此,建议将这段代码放在`#if DEBUG #endif`块中,以便在调试模式下使用。

需要注意的是,C#中没有宏(macros)的概念,宏是预处理器的一种特性,它会在编译前将宏名称替换为宏的实际内容。所以在C#中无法使用宏。

总结起来,为了在C#中获取当前代码的行号和文件名,可以使用`StackTrace`和`StackFrame`类。然而,这种方法会增加一些开销,因此建议在调试模式下使用,并将代码放在`#if DEBUG #endif`块中。需要注意的是,C#中没有宏的概念。

0
0 Comments

C#中是否存在和C++中的__LINE__和__FILE__等价的功能?原因是为了方便记录日志时自动获取文件名和行号。解决方法是使用Caller Information特性来获取文件路径和行号。以下是一种使用方法:

public void Log(string message,
        [CallerFilePath] string filePath = "",
        [CallerLineNumber] int lineNumber = 0)
{
    // Do logging
}

调用时只需要简单地调用`logger.Log("Hello!");`,编译器会自动填充文件名和行号。然而,这种方法对于常用的`Log(string format, params object[] args)`模式会产生问题,因为params必须是最后一个参数。除了将字符串格式的负担转移到调用方之外,是否有其他解决方法呢?

一种解决方法是创建一个包装类,其中包含多个重载方法,如`Log(string format, [CallerFilePath]..)`,`Log(string format, object o1, [CallerFilePath]...)`,`Log(string format, object o1, object o2, [CallerFilePath]...)`等。尽管这种方法并不理想,但是它是目前找到的最实用的解决方法之一。

以上是一个关于C#中是否存在和C++中的__LINE__和__FILE__等价的功能的讨论。通过使用Caller Information特性,可以方便地获取文件路径和行号。然而,对于常用的带有params的日志记录模式,需要使用其他解决方法来避免参数位置的问题。

0