在C#中编译时间反射

MgS*_*Sam 22 .net c# strong-typing compile-time magic-string

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

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

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

看起来这将是一个简单的补充,它将是一个非破坏性的变化,它将使许多开发人员受益匪浅.typeof()运算符已经执行了编译时反射的形式,因此看起来运算符nameof()(或类似的东西)将非常互补.

此外,有没有人知道这个功能的任何潜在问题?

谢谢您的帮助.

cyn*_*nic 14

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

  • Eric的回答似乎暗示使用Expressions解决了这个问题.但是,微软的许多技术都使用魔术字符串来表示类/属性:ASP .NET(Web Forms和MVC),Silverlight,WPF,Winforms; 他们都使用它们.更不用说您可能依赖的第三方开发人员.如果你看起来足够努力,你会发现使用它们的核心库.对我来说,这似乎是一个比async/await关键字解决的问题更普遍的问题(也是一个更容易解决的问题). (2认同)

MgS*_*Sam 13

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

链接到设计说明

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


Kim*_*imi 7

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

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);
}
Run Code Online (Sandbox Code Playgroud)