我正在构建一个C#项目的日志记录控件,并希望能够使用当前源代码文件,行,类,函数等的名称来调用它.PHP使用“魔术常量”,它们全部都是这个信息:http://php.net/manual/en/language.constants.predefined.php但是在C#编译器语言中我没有看到类似的东西。
我在寻找不存在的东西吗?
答案 0 :(得分:2)
您可以向系统询问堆栈跟踪,并且可以使用反射。细节即将到来。
__LINE__
__FILE__
__DIR__
__FUNCTION__ (does not really exist in C#)
__CLASS__
__METHOD__
__NAMESPACE__
这是一个开始:
Assembly.GetExecutingAssembly().FullName
System.Reflection.MethodBase.GetCurrentMethod().Name
您将在Debug(非优化)构建中获得更好的信息。 PhP可能总是能够访问所有这些东西,但它并不是这个星球上最快的枪。玩它,让我知道缺少什么。
答案 1 :(得分:2)
StackTrace / StackFrame类将为您提供相当多的内容,但构建起来可能非常昂贵。
答案 2 :(得分:2)
使用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此代码获取当前执行方法的调用堆栈,因此它比您要求的更多)
答案 3 :(得分:1)
有一些方法可以获取此类数据。这取决于你想要的数据。
__CLASS__
:如果你想要当前的类名,你需要使用反射。
__LINE__
:我不确定“文件的当前行号”是什么意思,我会猜测并说出文件中有多少行。这可以通过打开文件并进行行计数来完成。这可以通过File类完成,FileInfo类也可以工作。
__DIR__
:使用DirectoryInfo类完成文件目录。
__FUNCTION__
和__METHOD__
:函数名称(方法名称),可以通过反射检索。
__NAMESPACE__
:通过反射检索命名空间
答案 4 :(得分:1)
使用Type,您可以做的最好的事情是获取有关当前班级的信息。没有办法获取文件(虽然你通常应该坚持每个文件一个类),也不能使用行号,也不能使用Type
。
获取类型很简单,例如this.getType()
或typeof(MyClass)
。
您可以通过生成StackTrace
对象并从中检索StackFrame
来获取更具体的详细信息,但重复这样做是不错的主意。
我认为一个更重要的问题可能是:你为什么需要它们?对于跟踪调试,您的输出应该是临时的,因此无论它是否反映了准确的行号都无关紧要(实际上,我很少在跟踪调试中包含行号)。 Visual Studio作为真正的步调试器也非常有用。你真正需要文件,类,功能和行号吗?
编辑:对于错误检查,请使用例如它们要使用的异常:用于异常(错误)情况。该异常将生成指向您正确的问题的堆栈跟踪。
答案 5 :(得分:0)
以前的许多响应者提供了很好的信息;但是,我只是想指出访问StackFrame是非常昂贵的,除了特殊情况,可能不应该这样做。这些情况是用于调试极端情况或错误记录的极其繁琐的详细模式,对于错误,您可能已经有一个提供StackTrace的Exception实例。您的最佳表现将是使用Type建议的Bring S.此外,作为另一个设计考虑因素,记录到控制台可能会使应用程序速度降低几个数量级,具体取决于要显示的数据量。因此,如果有一个控制台接收器让编写器在工作线程上运行有很大帮助。