为何switch允许重复使用类型测试变量名,if语句却不行?
为什么switch模式匹配允许重复变量名,而if模式匹配不行?
你会发现下面两个方法逻辑完全一致,都是对object o做类型测试,但用switch语句时能重复使用变量名x,用if语句却不行,还会触发编译错误:Error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter。
代码示例:
public sealed class Test { public long GetLengthA(object o) { switch (o) { case Stream x: { return x.Length; } case Array x: // <-- 这里是允许的 { return x.Length; } } return 0; } public long GetLengthB(object o) { if (o is Stream x) { return x.Length; } else if (o is Array x) // <-- 这里不允许 { return x.Length; } return 0; } }
这本质是C#编译器对两种语句的作用域规则设计不同:
对于switch的case模式匹配:每个
case分支里的模式变量(比如这里的x),作用域被严格限定在当前case分支内部。而且因为switch的case分支是互斥执行的——同一时间只会进入其中一个case,永远不会出现两个x变量同时存在的情况,所以编译器允许重复命名。对于if/else if链:虽然逻辑上也是互斥执行,但编译器对模式变量的作用域判定更宽泛。第一个
if (o is Stream x)里的x,作用域会覆盖到后续的else if块(因为else if属于同一个if语句的后续分支,在同一个外层作用域下)。这时候再声明同名的x,就会和之前的变量产生命名冲突,触发CS0136错误。
简单来说,switch的case分支是独立的作用域隔间,而if/else if是共享外层作用域的分支,所以前者能重名,后者不行。
内容的提问来源于stack exchange,提问作者user3163495
相关产品推荐
相关产品推荐

