为什么以下代码会编译?我希望它会抱怨foo
没有在第二个案例分支中被宣布。编译器是否处理声明,使其适用于所有情况?
using System;
namespace Scratch
{
class Scratch
{
public static void Main()
{
var x = 2;
switch (x)
{
case 1:
var foo = "one";
Console.Out.WriteLine(foo);
break;
case 2:
foo = "two"; // is foo in scope here?
Console.Out.WriteLine(foo);
break;
}
}
}
}
答案 0 :(得分:8)
为什么以下代码会编译?
因为语言是在这个特定领域以脑死亡的方式设计的:(
局部变量的范围是声明它的块,并且在声明后可以在任何一点上以词汇方式访问。
不,我也不会那样设计语言。我不喜欢C#中的开关设计......
答案 1 :(得分:8)
@JonSkeet所说的是正确的:C / C ++ / C#意义上的“块”与逻辑意义上的“案例”不同。但他没有提到修复问题的“最佳实践”:如果要在switch语句的一个case中声明一个变量,最好将整个逻辑“case”包装在一个块中。这样,编译器识别的逻辑“案例”和实际“范围”将是同一个。
public static void Main()
{
var x = 2;
switch (x)
{
case 1: { // notice these braces I added
var foo = "one";
Console.Out.WriteLine(foo);
break;
}
case 2:
foo = "two"; // hooray! foo is no longer in scope here
Console.Out.WriteLine(foo);
break;
}
}
答案 2 :(得分:3)
为了使它不能编译,你可以用这样的大括号范围:
using System;
namespace Scratch
{
class Scratch
{
public static void Main()
{
var x = 2;
switch (x)
{
case 1:
{
var foo = "one";
Console.Out.WriteLine(foo);
break;
}
case 2:
{
foo = "two"; // is foo in scope here?
Console.Out.WriteLine(foo);
break;
}
}
}
}
这会强制var foo仅存在于该特定范围内。
答案 3 :(得分:1)
在C#中,变量的作用域是块级。由于块跟在switch语句之后,foo确实在两种情况下都在范围内。