提问人:user3163495 提问时间:7/29/2023 最后编辑:Rand Randomuser3163495 更新时间:7/29/2023 访问量:52
为什么“if”语句中的类型测试会泄露范围,而“switch”语句中的类型测试不会?[复制]
Why does type-testing in an "if" statement bleed scope, but type-testing in a "switch" statement does not? [duplicate]
问:
在以下示例方法中,使用语句和语句进行类型测试。这些方法在功能上是相同的。但是,该语句不允许在强制转换时重复使用相同的变量名。object o
switch
if
if
x
object o
为什么声明允许这样做,但声明不允许?switch
if
public sealed class Test
{
public long GetLengthA(object o)
{
switch (o)
{
case Stream x:
{
return x.Length;
}
case Array x: // <-- this is allowed
{
return x.Length;
}
}
return 0;
}
public long GetLengthB(object o)
{
if (o is Stream x)
{
return x.Length;
}
else if (o is Array x) // <-- this is NOT allowed
{
return x.Length;
}
return 0;
}
}
错误 CS0136:无法在此声明名为“x”的本地或参数 作用域,因为该名称在封闭的本地作用域中用于定义 本地或参数
答:
1赞
Harsh Shah
7/29/2023
#1
基本上在 switch-case 中,每个情况都被视为它自己的作用域/块,因此您可以重用变量名称,但使用 if-else 梯形图,整个函数都是作用域/块,因此您不能真正重用该名称。尝试将第二个变量 x 更改为 y 或其他变量。
请看这里,https://dotnetfiddle.net/LFyxXS
1赞
PMF
7/29/2023
#2
这基本上是因为在 if 语句中定义的变量的作用域确实超出了 if 测试的范围。
此代码有效(但见下文):
public long GetLengthB(object o)
{
if (o is Stream x)
{
return x.Length;
}
return x.Length * 2;
}
x
在作用域结束后有效,但是不能这样使用,因为编译器会抱怨它是未定义的,因为在条件为 false 的情况下它不会初始化。乍一听这可能很傻,但如果你反转条件,它现在就有意义了:
public long GetLengthB(object o)
{
if (!(o is Stream x))
{
throw new NotSupportedException(...);
}
return x.Length;
}
评论