使用C#6名称

时间:2016-03-30 14:00:27

标签: c# c#-6.0 nameof

C#6中最便捷的新功能之一是nameof,它允许程序员有效地消除magic strings的使用。

根据文档,nameof返回一个字符串:

  

用于获取变量,类型或成员的简单(非限定)字符串名称。

在以下代码示例中使用显式输入可以正常工作:

string magicString = nameof(magicString);

但是,在使用var keyword

的隐式输入时
var magicString = nameof(magicString);

编译器抛出错误:

  

无法使用局部变量' magicString'在宣布之前

然后,我对Visual Studio中提供的C#Interactive窗口进行了一些实验。同样,第一个例子运行正常,但第二个例子这次抛出了一个不同的错误:

  

错误CS7019:' magicString'的类型由于其初始化程序直接或间接引用了定义,因此无法推断。

nameof表达式清楚地返回一个字符串,那么为什么编译器在与初始化变量一起使用时会隐式输入它?

2 个答案:

答案 0 :(得分:23)

语言团队认为这不符合规范的复杂性。

您可以看到讨论here

这种行为的根本原因是规范说(§8.5.1)用var声明的名称在声明语句中不可见,因为在nameof之前,没有办法进入这可能是有效的。

  

隐式类型的局部变量声明受以下限制:

     
      
  • ...
  •   
  • 初始化表达式不能引用声明的变量本身
  •   

如果没有varint x = x = 1;int x = 1, y = x;等语句是合法的;使用var时,该格式中的任何内容均无效。

答案 1 :(得分:13)

声明变量并在同一语句中赋值的能力是语法糖。例如,当你这样说:

string magicString = nameof(magicString);

你真正说的是:

string magicString;
magicString = nameof(magicString);

由于已声明magicString,因此您可以在下一个逻辑语句中将其用作naemof运算符的一部分。这是因为magicString现在是后续语句可见的范围的一部分。

现在,当您使用var时,上述情况并不成立,因为使用var进行赋值的任何内容实际上只是一个语句的一部分,而不是两个语句的语法糖。上面的例子。变量magicString实际上不会在之后你的函数调用/运算符/赋值声明,因此变量不是范围的一部分,直到它具有完成了作业,即在下一个声明中。

SLaks提到了the original discussion about this issue,但the notes from this later C# design team meeting中关于“var var x = nameof(x)是否有效”这一问题的指出:

  

这与任何其他构造相同,即:not。这是   不是nameof的特例,它似乎并不值得特别   套管允许它。

换句话说,它并非特定于nameof