if语句后面的变量声明

时间:2010-03-22 23:54:56

标签: c# if-statement

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

以下代码是非法的

if (true)
    int i = 7;

但是,如果你用括号括起来,那就完全合法了。

if (true)
{
    int i = 7;
}

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

4 个答案:

答案 0 :(得分:80)

C# language specification区分三种类型的陈述(更多细节见第8章)。通常,您可以使用以下语句:

  • 带标签的陈述 - 我猜这是针对老式的goto陈述
  • 声明声明 - 这将是一个变量声明
  • 嵌入式声明 - 其中包括几乎所有剩余的声明

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

  

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

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

答案 1 :(得分:27)

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

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

  

... C#不是“猜猜用户是什么   意思是“语言......编译器   如果最好,设计会大声抱怨   匹配是不起作用的东西

答案 2 :(得分:10)

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

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

  

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

示例代码

void F(bool b) {
    if (b)
        int i = 44;
}

答案 3 :(得分:0)

在if的else部分添加关闭和打开括号,就像我在下面做的那样,而不是在添加它们之前我做的事情;

之前:导致错误:

protected void btnAdd_Click(object sender, EventArgs e)
    {
        if (btnAdd.Text == "ADD")
        {

            CATEGORY cat = new CATEGORY
            {

                NAME = tbxCategory.Text.Trim(),
                TOTALSALEVALUE = tbxSaleValue.Text.Trim(),
                PROFIT = tbxProfit.Text.Trim()

            };
            dm.AddCategory(cat, tbxCategory.Text.Trim());
        }
        else
        // missing brackets - this was causing the error
            var c = getCategory();
            c.NAME = tbxCategory.Text.Trim();
            c.TOTALSALEVALUE = tbxSaleValue.Text.Trim();
            c.PROFIT = tbxProfit.Text.Trim();
            dm.UpdateCategory(c);

        btnSearchCat_Click(btnSearchCat, e);
    }

之后:在else分支中添加了括号

protected void btnAdd_Click(object sender, EventArgs e)
    {
        if (btnAdd.Text == "ADD")
        {

            CATEGORY cat = new CATEGORY
            {

                NAME = tbxCategory.Text.Trim(),
                TOTALSALEVALUE = tbxSaleValue.Text.Trim(),
                PROFIT = tbxProfit.Text.Trim()

            };
            dm.AddCategory(cat, tbxCategory.Text.Trim());
        }
        else
        {
            var c = getCategory();
            c.NAME = tbxCategory.Text.Trim();
            c.TOTALSALEVALUE = tbxSaleValue.Text.Trim();
            c.PROFIT = tbxProfit.Text.Trim();
            dm.UpdateCategory(c);
        }
        btnSearchCat_Click(btnSearchCat, e);
    }