为什么声明(J ++);禁止? [英] Why was the statement (j++); forbidden?

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

问题描述

下面的代码是错误的(看到它上ideone ):

 公共类测试
{
公共静态无效的主要()
{
INT J = 5;
(J ++); //如果我们去掉(和),那么这编译罚款。
}
}




错误CS0201:只有分配,调用,递增,递减,在等待着,
新的对象表达式可以用来作为语句





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

  2. 为什么它不与括号编译?

  3. 为什么C#设计呀?


解决方案

赞赏的深刻见解。




我将尽我所能。



至于其他的答案已经注意到,这是怎么回事这里,编译器检测到一个表达的被用作<青霉>语句的。在许多语言 - C,JavaScript和许多其他人 - 这是完全合法的使用表达式作为一个声明。 2 + 2; 是这些语言的法律,即使这是没有效果的声明。一些表达式是只为自己时非常有用的,有些则表达式是有用的,只有他们的副作用(如为void返回方法的调用)和一些表情,不幸的是,这两个很有用的。 (像增量)



点是:报告仅包含的表达几乎肯定是错误的除非这些表达式通常被认为是更有益于其副作用比它们的值的。 C#的设计者希望找到一个中间接地,通过使被普遍认为是副作用的该表达式中,而不允许那些通常也认为是有用的它们的值。该组表达式他们发现在C#1.0中的增量,减量,方法调用,作业,而且有些争议,构造函数调用。






ASIDE:一个物体结构的通常认为是用作它产生的值,而不是对的副作用那个工程;在新的Foo()我认为允许; 是有点不好的特性的。特别是,我已经看到了在现实世界中的代码这种模式导致安全缺陷:

 赶上(FooException前){新BarException(除息); } 



这更是出奇地很难发现这一缺陷,如果代码是复杂的。






编译器的工作原理,因此检测到由不在该列表上表达的所有语句。特别是,括号表达式被确定为这一点 - 括号表达式。他们是不是允许作为声明表达式名单上,因此它们被禁止。



这一切都是在C#语言的设计原理的服务。 如果你输入(X ++); 你很可能做错事。这可能是一个错字M(X ++); 或有的只是事情。请记住,C#编译器团队的态度是不是的<​​em>我们可以想出一些方法来使这项工作?的C#编译器团队的态度是如果可行的代码看起来像一个可能的错,让我们通知开发商的。 C#开发人员喜欢这种态度。



现在,所有的说,其实有一些奇怪的情况下C#规范的确实的暗示或国家直接那个括号不允许,但C#编译器允许他们反正。在几乎所有这些情况下指定的行为和允许的行为之间的轻微差异是完全无害的,所以编译器作家并没有固定的这些小虫子。你可以阅读这些位置:



是否有与回报(myVar的)?


返回myVar的之间的差异

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.
    }
}

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

  1. Why does the code compile when we remove the parentheses?
  2. Why does it not compile with the parentheses?
  3. Why was C# designed that way?

解决方案

Deep insights appreciated.

I shall do my best.

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.)

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: 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.

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.

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:

Is there a difference between return myVar vs. return (myVar)?

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

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