在C#中编译时间reflection

我经常编写C#代码,必须使用魔术字符串来表达属性名称。 每个人都知道魔术弦的问题。 它们很难重构,它们没有编译时间检查,并且通常会导致难以诊断的问题。 然而,C#/ .NET 在整个地方使用它们来表示属性/类/方法名称。

这个问题已持续多年和多年,目前唯一可行的解​​决方案是使用表达式树,然后在运行时解析属性名称。 这可以让您获得令人满意的编译时检查,但它使代码复杂化(需要Expression类型的参数), 并且会产生运行时成本。

有没有人知道是否有一个特性考虑因为C#/ .NET添加编译时reflection来克服这个普遍存在的问题?

它似乎是一个很容易的补充,它将是一个非破坏性的变化,它将使许多开发人员受益匪浅。 typeof()运算符已经执行了编译时reflection的forms,因此看起来运算符nameof()(或类似的东西)将非常互补。

此外,有没有人知道这种function的任何潜在问题?

谢谢您的帮助。

直接来源 – 这是C#语言设计师的博客文章,这篇文章中的“用户”询问与您相同的问题并得到解答。 作者说,需要为每个你想要求的元数据项指定一个语法,这不是一件容易的事 – 即。 你想要哪个超载,如果你想要“info-of”方法并且方法是重载的? 如果涉及generics和显式接口实现怎么办? 等等。 事实certificate,虽然由于这些原因在2009年被认为不值得实施,但我们将在2015年的C#6中获得它 – 请参阅2014年7月9日的C#语言设计说明 。

在C#6.0中,添加了一个新的运算符nameof ,它允许您在编译时获取属性,类,字段,事件和变量的名称。

链接到设计说明

不再反映编译器在设计时已经知道的信息!

我遇到了类似的问题。 最近才发现.NET Framework 4.5具有一个名为Caller Info属性的function。 通过使用这些,您可以在编译时获取有关调用方的信息。 您可以获取源代码的文件路径,源代码中的行号以及调用者的成员名称。

 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编译器提出要求,该编译器承诺提供“编译即服务”。