当前位置:  开发笔记 > 编程语言 > 正文

为什么是陈述(j ++); 禁止?

如何解决《为什么是陈述(j++);禁止?》经验,为你挑选了3个好方法。

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

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

错误CS0201:只能将赋值,调用,递增,递减,等待和新对象表达式用作语句

    为什么在删除括号时编译代码?

    为什么不用括号编译?

    为什么C#这样设计?

Eric Lippert.. 220

深刻的见解表示赞赏.

我会尽我所能.

正如其他答案所指出的,这里发生的是编译器检测到表达式被用作语句.在许多语言中--C,JavaScript和许多其他语言 - 将表达式用作语句是完全合法的. 2 + 2;这些语言是合法的,即使这是一个没有效果的陈述.有些表达式只对它们的值有用,有些表达式只对它们的副作用有用(比如调用void返回方法),不幸的是,有些表达式对两者都很有用.(像增量一样.)

要点:只包含表达式的语句几乎肯定是错误的,除非这些表达式通常被认为对副作用比它们的值更有用.C#设计者希望通过允许通常被认为是副作用的表达来找到中间立场,同时禁止那些通常被认为对其价值有用的表达.他们在C#1.0中确定的表达式集是增量,减量,方法调用,赋值以及有点争议的构造函数调用.


ASIDE:人们通常认为物体结构用于产生它所产生的价值,而不是用于施工的副作用; 在我看来,允许new Foo();有点不合时宜.特别是,我在实际代码中看到了这种模式导致了安全性缺陷:

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

如果代码复杂,可能会很难发现这个缺陷.


因此,编译器可以检测由不在该列表上的表达式组成的所有语句.特别是,带括号的表达式被标识为 - 带括号的表达式.它们不在"允许的语句表达式"列表中,因此不允许使用它们.

所有这些都是为了满足C#语言的设计原则.如果你打字,(x++);你可能做错了什么.这可能是一个错字M(x++);或一些正义的东西.请记住,C#编译器团队的态度是不是" 我们可以想出一些方法来使这项工作? " C#编译器团队的态度是" 如果可行的代码看起来像一个可能的错误,让我们通知开发商 ".C#开发人员喜欢这种态度.

现在,所有的说,其实有一些奇怪的情况下,C#的规格暗示或直接说括号不允许的状态,但C#编译器允许他们反正.在几乎所有这些情况下,指定行为和允许行为之间的微小差异是完全无害的,因此编译器编写者从未修复过这些小错误.你可以在这里阅读:

返回myVar与return(myVar)之间有区别吗?



1> Eric Lippert..:

深刻的见解表示赞赏.

我会尽我所能.

正如其他答案所指出的,这里发生的是编译器检测到表达式被用作语句.在许多语言中--C,JavaScript和许多其他语言 - 将表达式用作语句是完全合法的. 2 + 2;这些语言是合法的,即使这是一个没有效果的陈述.有些表达式只对它们的值有用,有些表达式只对它们的副作用有用(比如调用void返回方法),不幸的是,有些表达式对两者都很有用.(像增量一样.)

要点:只包含表达式的语句几乎肯定是错误的,除非这些表达式通常被认为对副作用比它们的值更有用.C#设计者希望通过允许通常被认为是副作用的表达来找到中间立场,同时禁止那些通常被认为对其价值有用的表达.他们在C#1.0中确定的表达式集是增量,减量,方法调用,赋值以及有点争议的构造函数调用.


ASIDE:人们通常认为物体结构用于产生它所产生的价值,而不是用于施工的副作用; 在我看来,允许new Foo();有点不合时宜.特别是,我在实际代码中看到了这种模式导致了安全性缺陷:

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

如果代码复杂,可能会很难发现这个缺陷.


因此,编译器可以检测由不在该列表上的表达式组成的所有语句.特别是,带括号的表达式被标识为 - 带括号的表达式.它们不在"允许的语句表达式"列表中,因此不允许使用它们.

所有这些都是为了满足C#语言的设计原则.如果你打字,(x++);你可能做错了什么.这可能是一个错字M(x++);或一些正义的东西.请记住,C#编译器团队的态度是不是" 我们可以想出一些方法来使这项工作? " C#编译器团队的态度是" 如果可行的代码看起来像一个可能的错误,让我们通知开发商 ".C#开发人员喜欢这种态度.

现在,所有的说,其实有一些奇怪的情况下,C#的规格暗示或直接说括号不允许的状态,但C#编译器允许他们反正.在几乎所有这些情况下,指定行为和允许行为之间的微小差异是完全无害的,因此编译器编写者从未修复过这些小错误.你可以在这里阅读:

返回myVar与return(myVar)之间有区别吗?


Re:"人们通常会认为构造函数调用是用于它产生的值,而不是构造的副作用;在我看来这有点像错误":我想象这个决定中的一个因素是因为如果编译器禁止它,在你*调用副作用的情况下就不会有任何干净的修复.(大多数其他禁止的表达式语句有无关的部分,没有任何目的,可以删除,除了`...?...:...`,其中修复是使用`if` /`else`代替.)
@McBrainy:你是对的.我错误地记错了拼写错误造成的缺陷; 我会查看我的笔记.与此同时,我删除了有问题的陈述,因为它与这里的大点没有密切关系.

2> Frank Bryce..:

在C#语言规范中

表达式语句用于计算表达式.可用作语句的表达式包括方法调用,使用new运算符的对象分配,使用=的赋值和复合赋值运算符,使用++和 - 运算符的增量和减量运算以及await表达式.

将括号括在语句周围会创建一个新的所谓括号表达式.从规格:

括号表达式由括在括号中的表达式组成....通过计算括号内的表达式来计算括号表达式.如果括号内的表达式表示名称空间或类型,则会发生编译时错误.否则,parenthesized-expression的结果是包含表达式的计算结果.

由于带括号的表达式未列为有效的表达式语句,因此根据规范,它不是有效的语句.为什么设计师选择这样做是任何人的猜测,但我的赌注是因为如果整个陈述包含在括号中,括号不起作用:stmt并且(stmt)完全相同.


好的,我的坏.答案是:*因为,**根据规范**,它不是一个有效的陈述.*你有它:**设计**的原因!
@Servy:如果你仔细阅读,它会比那更微妙.所谓的"表达式语句"确实是一个有效的语句,规范列出了可以是有效语句的表达式类型.但是,我从规范中重复一遍,称为"括号表达式"的表达式类型不在可用作有效表达式语句的有效表达式列表中.
"OP"对语言设计一无所知.他只是想知道为什么这是一个错误.答案是:*因为它不是有效的声明*.
@Servy JohnCarpenter不只是说"你不能那样做".他说,你被困惑的那两件事情是不一样的.j ++是一个表达式语句,而(j ++)是一个带括号的表达式.OP现在突然知道它们之间的差异和它们是什么.这是一个很好的答案.它回答了他的问题的主体而不是标题.我认为很多争论来自问题标题中的"设计"一词,但这并不是设计师必须回答的,只是从规范中收集而来.
问题不是要求一个深刻的,设计驱动的理由,为什么语言被设计为以这种方式处理这种语法 - 他问为什么一段代码编译时另一段代码(初学者看起来应该表现如何)完全相同)无法编译.这篇文章回答了这一点
@Servy:"为什么这个简单的代码会给出错误""为什么它不能用括号编译?" 我不确定如何解释这些问题.这对我来说似乎非常简单.也许你在问题标题中的C#之后就出现了"设计"这个词.如果这个词被删除了,那么你剩下的就是这里已经回答的确切问题.

3> CaldasGSM..:

因为周围的括号i++正在创建/定义表达式..因为错误消息说...一个简单的表达式不能用作语句.

为什么语言设计成这种方式?防止错误,将错误的表达式作为语句,不产生像代码一样的副作用

int j = 5;
j+1; 

第二行没有效果(但你可能没有注意到).但不是编译器删除它(因为代码不需要).明确要求你删除它(所以你会意识到或错误)或修复它,以防你忘记输入内容.

编辑:

使关于bracked的部分更清晰.. c#中的括号(除了其他用途,如强制转换和函数调用),用于对表达式进行分组,并返回单个表达式(子表达式的make).

在那个级别的代码中只允许staments ..所以

j++; is a valid statement because it produces side effects

但是通过使用bracked你将它变成表达式

myTempExpression = (j++)

还有这个

myTempExpression;

是无效的,因为编译器不能确保表达式作为副作用.(不是没有引起停止问题)..

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有