Embedded statement cannot be a declaration or labeled statement
Posted on 2009-02-03 23:12 Charles Chen 阅读(3717) 评论(0) 编辑 收藏 举报Hi All Friends,今天在写程序的时候突然遇到这样的一个编译错误:Embedded statement cannot be a declaration or labeled statement
一个很普通又低级的编译错误,然而要弄清为什么会出现错误,还的牵涉到变量的作用域:
代码样例如下:
{
if (true)
string text = "Charles";
}
编译时候会出现:Embedded statement cannot be a declaration or labeled statement
正确的写法是:
{
if (true)
{
string text = "Charles";
}
}
{
string text;
if (true)
text = "Charles";
}
总结:
就是说如果在代码块(这里是if)中申明一个类型变量的话:
1.要么申明变量放到代码块外(if),
2.要么这个代码块用{}.
反之:如果你不用{}且在代码块中申明变量的话,根据变量的作用域,这个变量根本无法被访问到。所以C#编译器会给出一个错误(Error)。
另外便于理解,这里我摘录了C#入门经典中"变量的作用域的例子",更能加深对变量作用域的理解:
下面摘自《C#入门经典3》相关章节:
变量的作用域包含定义它们的代码块和直接嵌套在其中的代码块。这也可以应用到其他代码块上,例如分支和循环结构的代码块。考虑下面的代码:
for (i = 0; i < 10; i++)
{
string text = "Line " + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
string text;
for (i = 0; i < 10; i++)
{
text = "Line " + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
这段代码也会失败,原因是变量必须在使用前声明和初始化,而text是在for循环中初始化的。赋给text的值在循环块退出时就丢失了。但是还可以进行如下修改:
string text = "";
for (i = 0; i < 10; i++)
{
text = "Line " + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
在循环中最后赋给text的值可以在循环外部访问。
可以看出,这个主题的内容需要花一点时间来掌握。在前面的示例中,循环之前赋给text空字符串,而在循环之后的代码中,该text就不会是空字符串了,其原因不能立即看出。
这种情况的解释涉及到分配给text变量的内存空间,实际上任何变量都是这样。
只声明一个简单的变量类型,并不会引起其他的变化。只有在给变量赋值后,这个值才占用一块内存空间。如果这种占据内存空间的行为在循环中发生,该值实际上定义为一个局部值,在循环的外部会超出了其作用域。即使变量本身没有局部化到循环上,循环所包含的值也局部化到该循环上。但是,在循环外部赋值可以确保该值是主体代码的局部值,在循环内部它仍处于其作用域中。这意味着变量在退出主体代码块之前是没有超出作用域的,所以可以在循环外部访问它的值。
幸而,C#编译器可检测变量作用域的问题,它生成的响应错误信息可以帮助我们理解变量作用域的问题。
最后一个要注意的问题是,应采用“最佳实践”。一般情况下,最好在声明和初始化所有的变量后,再在代码块中使用它们。一个例外是把循环变量声明为循环块的一部分。
Charles Chen
Email: gotosunny@msn.com
MSN: gotosunny@msn.com