为什么是这个语句(j ++);禁止? [英] Why was the statement (j++); forbidden?

查看:170
本文介绍了为什么是这个语句(j ++);禁止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码错误(请参阅 ononeone ):

The following code is wrong (see it on ideone):

public class Test
{
    public static void Main()
    {
        int j = 5;
        (j++);      // if we remove the "(" and ")" then this compiles fine.
    }
}




错误CS0201:Only分配,调用,增量,减量,等待和
新的对象表达式可以用作语句

error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement




  1. 为什么我们删除括号时编译代码?

  2. 为什么不用括号编译?

  3. 为什么C#设计那个方式?


推荐答案


深入见解赞赏。 >

Deep insights appreciated.

我将尽全力。

正如其他答案所指出的那样,这里是编译器正在检测到一个表达式被用作语句。在许多语言中,C,JavaScript和许多其他语言 - 使用表达式作为语句是完全合法的。 2 + 2; 在这些语言中是合法的,即使这是一个没有效果的声明。一些表达式仅对于它们的值是有用的,一些表达式仅对它们的副作用(例如调用void返回方法)是有用的,而一些表达式对于两者都是有用的。 (如增量。)

As other answers have noted, what's going on here is the compiler is detecting that an expression is being used as a statement. In many languages -- C, JavaScript, and many others -- it is perfectly legal to use an expression as a statement. 2 + 2; is legal in these languages, even though this is a statement that has no effect. Some expressions are useful only for their values, some expressions are useful only for their side effects (such as a call to a void returning method) and some expressions, unfortunately, are useful for both. (Like increment.)

点:仅由表达式组成的语句几乎肯定是错误,除非这些表达式通常被认为对其副作用更有用比他们的价值。 C#设计师希望找到一个中间的地方,允许通常被认为是副作用的表达,同时不允许通常被认为对他们的价值观有用的表达。他们在C#1.0中确定的一组表达式是递增,递减,方法调用,赋值以及有争议的构造函数调用。

Point being: statements that consist only of expressions are almost certainly errors unless those expressions are typically thought of as more useful for their side effects than their values. C# designers wished to find a middle ground, by allowing expressions that were generally thought of as side-effecting, while disallowing those that are also typically thought of as useful for their values. The set of expressions they identified in C# 1.0 were increments, decrements, method calls, assignments, and somewhat controversially, constructor invocations.

ASIDE:一般通常认为对象构造用于生成的值,而不是副作用那个工程;在我看来,允许 new Foo(); 有点不正常。特别是,我在现实世界的代码中看到这种模式导致安全性缺陷:

ASIDE: One normally thinks of an object construction as being used for the value it produces, not for the side effect of the construction; in my opinion allowing new Foo(); is a bit of a misfeature. In particular, I've seen this pattern in real-world code that caused a security defect:

catch(FooException ex) { new BarException(ex); } 

如果代码很复杂,发现这个缺陷可能会令人惊讶。

It can be surprisingly hard to spot this defect if the code is complicated.

因此,编译器可以检测由不在该列表中的表达式组成的所有语句。特别地,括号表达式被认为只是括号表达式。它们不在允许作为语句表达式的列表中,因此它们被禁止。

The compiler therefore works to detect all statements that consist of expressions that are not on that list. In particular, parenthesized expressions are identified as just that -- parenthesized expressions. They are not on the list of "allowed as statement expressions", so they are disallowed.

所有这些都是为了C#语言的设计原则。 如果您键入(x ++); ,则可能会出现错误的。这可能是 M(x ++); 或某些只是事情的错字。记住,C#编译器团队的态度不是我们可以找出一些方法来实现这个工作吗?C#编译器团队的态度是如果可能的代码看起来像是可能的话错误,让我们通知开发人员。 C#开发人员喜欢这样的态度。

All of this is in service of a design principle of the C# language. If you typed (x++); you were probably doing something wrong. This is probably a typo for M(x++); or some just thing. Remember, the attitude of the C# compiler team is not "can we figure out some way to make this work?" The attitude of the C# compiler team is "if plausible code looks like a likely mistake, let's inform the developer". C# developers like that attitude.

现在,所有这些说,实际上有一些奇怪的情况,C#规范括号不允许,但C#编译器允许它们。在几乎所有这些情况下,指定行为与允许的行为之间的微小差异是完全无害的,所以编译器编写者从未修复过这些小错误。你可以在这里阅读:

Now, all that said, there actually are a few odd cases where the C# specification does imply or state outright that parentheses are disallowed but the C# compiler allows them anyways. In almost all those cases the minor discrepancy between the specified behaviour and the allowed behaviour is completely harmless, so the compiler writers have never fixed these small bugs. You can read about those here:

返回myVar与return(myVar)之间有差异吗?

这篇关于为什么是这个语句(j ++);禁止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆