22

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

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

有谁知道 C#/.NET 是否曾经考虑过添加编译时反射来克服这个普遍存在的问题?

看起来这将是一个简单的添加,它将是一个非破坏性的更改,它将极大地使许多开发人员受益。typeof() 运算符已经执行了一种编译时反射形式,因此看起来像运算符 nameof() (或类似的东西)将是非常互补的。

此外,有谁知道此类功能的任何潜在问题?

谢谢您的帮助。

4

4 回答 4

14

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

于 2012-02-17T20:47:54.213 回答
13

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

链接到设计说明

无需再考虑编译器在设计时已经知道的信息!

于 2015-01-30T21:00:18.777 回答
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);
}
于 2015-01-29T14:54:17.467 回答
0

然而,C#/.NET 到处都使用它们来表示属性/类/方法名称。

首先:我不同意。有某些框架(例如,WebForms)到处都使用魔术字符串,但 C# 和 .NET 的基础库往往能很好地避免这些事情。

其次:在许多使用魔术字符串的情况下,ReSharper 能够识别错误。这可以帮助很多。

最后:您所要求的可以通过 Roslyn 编译器实现,它承诺提供“编译即服务”。

于 2012-02-17T20:57:11.163 回答