下面的代码是错误的(看一下关于ideone http://ideone.com/vSoRsM):
public class Test
{
public static void Main()
{
int j = 5;
(j++); // if we remove the "(" and ")" then this compiles fine.
}
}
错误 CS0201:仅赋值、调用、递增、递减、等待和
new对象表达式可以用作语句
- 为什么当我们删除括号时代码会编译?
- 为什么带括号编译不通过?
- C# 为什么要这样设计?
深刻的见解受到赞赏。
我会尽力而为。
正如其他答案所指出的,这里发生的事情是编译器正在检测到表达正在被用作陈述。在许多语言中——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# 规范does暗示或直接声明不允许使用括号,但 C# 编译器无论如何都允许使用括号。在几乎所有这些情况下,指定行为和允许行为之间的微小差异是完全无害的,因此编译器编写者从未修复这些小错误。您可以在这里阅读相关内容:
return myVar 与 return (myVar) 之间有区别吗? https://stackoverflow.com/questions/2186595/is-there-a-difference-between-return-myvar-vs-return-myvar/2187498#2187498
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)