if语句后面的变量声明

Ant*_*ram 59 c# if-statement

另一个论坛上出现了一个问题,我知道如何修复它,但它揭示了我特有的编译器功能.该人收到错误"嵌入式语句不能是声明或标记语句",因为他们在没有括号的if语句后声明了变量.这不是他们的意图,但是他们在if语句之后立即注释掉了代码行,这使得变量声明成为执行的事实上的代码行.无论如何,这就是背景,这让我想到了这一点.

以下代码是非法的

if (true)
    int i = 7;
Run Code Online (Sandbox Code Playgroud)

但是,如果你用括号括起来,那一切都是合法的.

if (true)
{
    int i = 7;
}
Run Code Online (Sandbox Code Playgroud)

这两段代码都没用.然而第二个是好的.这种行为的具体解释是什么?

Tom*_*cek 80

C#语言规范三种类型的报表(详见第8章)进行了区分.通常,您可以使用以下语句:

  • label-statement - 我猜这是老式的goto陈述
  • 声明 - 声明 - 这将是一个变量声明
  • embedded-statement - 包括几乎所有剩余的语句

if声明中,body必须是embedded-statement,这解释了为什么第一个版本的代码不起作用.以下是if规范的语法(第8.7.1节):

if(boolean-expression)embedded-statement
if(boolean-expression)embedded-statement else embedded-statement

变量声明是声明语句,因此它不能出现在正文中.如果将声明括在括号中,您将获得一个语句块,这是一个嵌入式语句(因此它可以出现在该位置).


Zac*_*son 27

如果不包括括号,它将执行下一行,就像它被括号括起来一样.因为在该行中声明一个变量没有多大意义(你永远无法使用它),C#编译器将不允许这样做以防止你在不知情的情况下意外地执行它(这可能会引入微妙的错误) ).

以下是Eric Lippert 关于名称解析的SO答案的C#编译器的一部分:

... C#不是"猜猜用户的意思"语言......如果最佳匹配是不起作用的话,设计编译器会大声抱怨

  • 是.当您包含括号时,编译器的意图是绝对清楚的,因此它将允许这样做.C#编译器不允许没有括号,因为不清楚你的实际意图是声明一个无用的变量. (3认同)

Jar*_*Par 10

所有编译器都允许您编译无用或使用率极低的代码.开发人员可以使用该语言创建没有用的构造的方式太多了.让编译器捕获所有这些只是太费力而且通常不值得.

第二种情况直接在8.0节开头的C#语言规范中调用

该示例导致编译时错误,因为if语句需要嵌入语句而不是if语句的语句.如果允许此代码,那么将声明变量i,但它永远不会被使用.但请注意,通过将i的声明放在块中,该示例是有效的.

示例代码

void F(bool b) {
    if (b)
        int i = 44;
}
Run Code Online (Sandbox Code Playgroud)