深刻的见解表示赞赏。
我会尽力的
正如其他答案所指出的那样,这里发生的是编译器正在检测表达式正在用作语句。在许多语言(C,JavaScript和许多其他语言)中,使用表达式作为语句是完全合法的。 2 + 2;
即使这些陈述无效,在这些语言中也是合法的。一些表达式仅对它们的值有用,某些表达式仅对它们的副作用(如对void返回方法的调用)有用,而不幸的是,某些表达式对它们都有用。(如增量。)
要点是:仅由表达式组成的语句几乎可以肯定是错误,除非通常认为这些表达式在副作用方面比其值更有用。C#设计师希望通过允许通常被认为是副作用的表达式,而不允许那些通常被认为对其值有用的表达式来找到中间立场。他们在C#1.0中标识的表达式集是增量,减量,方法调用,赋值,以及在构造程序调用中引起争议的一组表达式。
旁白:人们通常认为对象构造是用于其产生的价值的,而不是该构造的副作用;我认为允许这样new Foo();
做有点不妥当。特别是,我在现实世界的代码中看到了这种模式,该模式导致了安全缺陷:
catch(FooException ex) { new BarException(ex); }
如果代码很复杂,则很难发现此缺陷。
因此,编译器将检测包含不在该列表中的表达式的所有语句。特别是,带括号的表达式仅被标识为带括号的表达式。它们不在“允许作为语句表达式”列表中,因此是不允许的。
所有这些都符合C#语言的设计原则。如果您键入(x++);
,可能是您做错了什么。这可能是错别字M(x++);
或只是一些事情。记住,C#编译器团队的态度不是“ 我们能找到某种方法使这项工作吗? ” C#编译器团队的态度是“ 如果看似合理的代码看起来像是可能的错误,那就通知开发人员 ”。C#开发人员喜欢这种态度。
现在,尽管如此,实际上在一些奇怪的情况下,C#规范确实暗示或完全声明不允许使用括号,但C#编译器仍然允许使用括号。在几乎所有这些情况下,指定行为与允许行为之间的微小差异都是完全无害的,因此编译器编写者从未修复过这些小错误。您可以在这里阅读有关内容:
return myVar与return(myVar)之间有区别吗?