【问题标题】:"Magic" constants in C# like PHP has?像 PHP 一样的 C# 中的“魔术”常量?
【发布时间】:2010-07-19 21:22:31
【问题描述】:

我正在为一个 C# 项目构建一个日志控件,并希望能够使用当前源代码文件、行、类、函数等的名称来调用它。PHP 使用具有所有此信息:http://php.net/manual/en/language.constants.predefined.php 但我在 C# 编译器语言中没有看到类似的内容。

我在寻找不存在的东西吗?

【问题讨论】:

  • 您可能想要研究 C# 反射。我不认为 C# 有类似这些常量的东西,你可能能得到的最接近的是 C# 预处理器(我什至不确定)。
  • 对于__FUNCTION__,请参阅C# version of __FUNCTION__ macro
  • 请注意,使用反射(GetCurrentMethod 等)会抑制内联,从而导致性能下降。

标签: c# php


【解决方案1】:

使用 StackTrace/StackFrame 类,您可以让您的控件找出调用它的位置,而不是向其传递该信息:

private static StringBuilder ListStack(out string sType)
{
  StringBuilder sb = new StringBuilder();
  sType = "";

  StackTrace st = new StackTrace(true);
  foreach (StackFrame f in st.GetFrames())
  {
    MethodBase m = f.GetMethod();
    if (f.GetFileName() != null)
    {
      sb.AppendLine(string.Format("{0}:{1} {2}.{3}",
        f.GetFileName(), f.GetFileLineNumber(),
        m.DeclaringType.FullName, m.Name));

      if (!string.IsNullOrEmpty(m.DeclaringType.Name))
        sType = m.DeclaringType.Name;
    }
  }

  return sb;
}

(我used这段代码是为了获取当前执行方法的调用堆栈,所以它比你要求的要多)

【讨论】:

  • 频繁调用该方法可能会影响您的应用程序性能。
【解决方案2】:

StackTrace/StackFrame 类将为您提供相当多的功能,尽管它们的构建成本可能非常高。

【讨论】:

    【解决方案3】:

    您可以向系统请求堆栈跟踪,并且可以使用反射。详细信息即将发布。

    __LINE__ 
    __FILE__ 
    __DIR__ 
    __FUNCTION__  (does not really exist in C#) 
    __CLASS__
    __METHOD__
    __NAMESPACE__
    

    这是一个开始:

    您将在调试(非优化)构建中获得更好的信息。 PhP 可能总是可以使用所有这些东西,但它并不是这个星球上最快的枪。玩它,让我知道缺少什么。

    【讨论】:

    • 正如所有其他人所说,反射很昂贵,所以......在仅调试中执行此操作。在 Release 中,您可以硬编码方法名称,因为您知道它:)
    【解决方案4】:

    有一些方法可以获取此类数据。这取决于你想要什么数据。

    __CLASS__ :如果你想要当前的类名,你需要使用反射。

    __LINE__ :我不确定“文件的当前行号”是什么意思,我会猜测一下,它是文件中有多少行。这可以通过打开文件并进行行数来完成。这可以通过 File 类来完成,FileInfo 类也可以工作。

    __DIR__ :通过DirectoryInfo类获取文件目录。

    __FUNCTION____METHOD__:函数名(方法名),这个可以通过反射获取。

    __NAMESPACE__ :通过反射检索命名空间

    【讨论】:

    • re: __LINE__:这将是 __Line__ 调用出现在文件中的行号。
    【解决方案5】:

    使用Type,您真正能做的最好的事情就是获取有关当前课程的信息。没有办法获取文件(尽管您通常应该坚持每个文件一个类),也没有行号,也没有使用 Type 的函数。

    获取类型很简单,例如this.getType()typeof(MyClass)

    您可以通过生成StackTrace 对象并从中检索StackFrame 来获取更具体的详细信息,但重复这样做是一个坏主意。

    我认为一个更重要的问题可能是:您为什么需要它们?对于跟踪调试,您的输出应该是临时的,因此它是否反映了准确的行号并不重要(事实上,我很少在跟踪调试中包含行号)。 Visual Studio 作为真正的步进调试器也非常有用。你真正需要什么文件、类、函数和行号?

    编辑:对于错误检查,使用应该使用的异常:用于异常(错误)情况。该异常将生成一个堆栈跟踪,将您指向问题所在。

    【讨论】:

      【解决方案6】:

      许多以前的响应者都提供了很好的信息;但是,我只是想指出,访问 StackFrame 非常昂贵,除非特殊情况,否则可能不应该这样做。这些情况是用于调试极端情况或错误日志的极其冗长的模式,对于错误,您可能已经有一个提供 StackTrace 的 Exception 实例。您的最佳表现将是使用 Type 建议的带 S。此外,作为另一个设计考虑,记录到控制台可能会使您的应用程序速度降低几个数量级,具体取决于要显示的数据量。因此,如果有一个控制台接收器让编写器在工作线程上运行会非常有帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-19
        • 1970-01-01
        • 2010-09-18
        • 2023-04-07
        • 2018-09-09
        相关资源
        最近更新 更多