编程语言
首页 > 编程语言> > c# – 在范围成员中隐藏时可以使用nameof吗?

c# – 在范围成员中隐藏时可以使用nameof吗?

作者:互联网

请考虑以下遗留代码:

public class Foo
{
    public void Blah(string frob)
    {
        if (frob == null)
            throw new ArgumentException("frob");
    }

    public string nameof()
    {
        //boring code
    }
}

现在假设这部分代码正在重构,我们想以下列方式重构Blah:

public void Blah(string frob)
{
    if (frob == null)
        throw new ArgumentException(nameof(frob)); //nameof contextual keyword
}

此解析器不会选择上下文关键字nameof,并将解析为给出编译时错误(没有现有重载)的私有方法名称.为什么?如果方法是nameof(对象o),我会理解这一点.

有没有我可以让编译器解析为内置名称?我是否需要重构重命名方法的代码?

上面的示例是一个非常简化的场景,实际上,方法的名称在反射中被广泛使用,并且需要花费时间和精力来确保在任何地方正确地完成重命名.

解决方法:

This parser will not choose the contextual keyword nameof and will resolve to the private method nameof giving a compile time error (no existing overload). Why?

“为什么”问题含糊不清;我将假设这个问题意味着“在设计这样的功能时会考虑哪些设计因素?”

创建新的上下文关键字时的高阶考虑因素是确保在新编译器中编译时没有现有程序更改的含义.例如,当我编写代码以在C#3中添加var时,我们小心翼翼地确保这一点

class var { public implicit operator var(int x) { ... } }
...
var y = 3;

将类型var分配给y,而不是int.虽然这样的程序不太可能,但我们想要打破任何人.

类似地,yield return的语法是yield return而不仅仅是yield,因为*没有程序曾经有过yield return.但很多程序可能会说收益率(123);

类似地,await运算符仅在异步方法内有意义,而from和select等在查询推理中是有意义的.

因此,nameof必须表示名为nameof的标识符(如果一个在范围内),而不是运算符.请注意,C#不会尝试回溯.它并没有说“好吧,它的范围,但是这导致了重载分辨率错误,因此我将回溯并假设它是关键字……”不,不,这是可怕的推理.标识符名称在范围内,因此这几乎肯定是C#6之前的程序. 99.9%的可能性是该程序中每次使用nameof都打算引用标识符.

C#的基本设计原则是“如果看起来很奇怪,请告诉开发人员,以便他们了解问题.”您现在已经完全意识到程序中存在严重问题,现在您可以尝试修复它. C#不是为了找到编译程序的任何可能的解释而设计的,无论多么奇怪和不可能.

标签:c,nameof
来源: https://codeday.me/bug/20190611/1218081.html