另一个论坛上出现了一个问题,我知道如何修复它,但它揭示了我特有的编译器功能。该人收到错误“嵌入式语句不能是声明或标记语句”,因为他们在没有括号的if语句后声明了变量。这不是他们的意图,但是他们在if语句之后立即注释掉了代码行,这使得变量声明成为执行的事实上的代码行。无论如何,这就是背景,这让我想到了这一点。
以下代码是非法的
if (true)
int i = 7;
但是,如果你用括号括起来,那就完全合法了。
if (true)
{
int i = 7;
}
这两段代码都没用。然而第二个是好的。这种行为的具体解释是什么?
答案 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);
}