C#中的编译时反射
本文关键字:反射 编译 | 更新日期: 2023-09-27 18:25:11
我经常编写C#代码,这些代码必须使用魔术字符串来表示属性名称。每个人都知道魔术串的问题。它们很难重构,没有编译时检查,而且通常会导致难以诊断的问题。然而,C#/.NET到处都使用它们来表示属性/类/方法名。
这个问题已经存在多年了,目前唯一可行的解决方案是使用表达式树,然后在运行时解析属性名称。这可以获得令人满意的编译时检查,但会使代码复杂化(需要Expression类型的参数),和会导致运行时开销。
有人知道C#/.NET是否考虑过添加编译时反射来克服这个普遍存在的问题吗?
这似乎是一个很容易添加的内容,这将是一个不间断的更改,它将极大地造福于许多开发人员。typeof()操作符已经执行了某种形式的编译时反射,所以看起来操作符名称of(或类似的东西)是非常好的。
此外,有人知道这样一个功能可能存在的问题吗?
谢谢你的帮助。
来源直接-这是一篇由C#语言设计师撰写的博客文章,文章中的"用户"提出了与您相同的问题,并得到了回答。作者说,需要为你想要的每个元数据项指定一个语法,这并不是一件小事——比如,如果你想要"info of"方法,而该方法被重载了,你想要哪个重载?如果涉及泛型和显式接口实现,该怎么办?等等。事实证明,尽管由于这些原因,它在2009年被认为不值得实施,但我们将在2015年在C#中实现它——参见2014年7月9日的C#语言设计说明。
在C#6.0中,添加了一个新的运算符nameof
,它将允许您在编译时获得属性、类、字段、事件和变量的名称。
设计说明链接
不再反映编译器在设计时已经知道的信息!
我也遇到了类似的问题。最近才发现.NET Framework 4.5
具有一个名为"呼叫者信息"属性的功能。通过使用这些,您可以在编译时获得有关方法调用方的信息。您可以获取源代码的文件路径、源代码中的行号以及调用方的成员名称。
public void DoProcessing()
{
TraceMessage("Something happened.");
}
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
然而,C#/.NET在所有地方都使用它们来表示属性/类/方法名。
首先:我不同意。有些框架(例如WebForms)到处都在使用魔术串,但C#和.NET的基本库往往很好地避免了这种情况。
第二:在许多使用魔术串的情况下,ReSharper能够识别错误。这会有很大帮助。
最后:您的要求可以通过Roslyn编译器实现,该编译器承诺提供"编译即服务"。