.NET 4.6.1中内联变量声明用==false替代取反编译失败问题咨询
为什么Bar()方法在.NET 4.6.1中会触发未赋值变量编译错误?
先看你给出的两个代码片段:
Foo()方法(可正常编译):
void Foo(object sender, EventArgs e) { if (!(sender is ComboBox comboBox)) return; comboBox.DropDownWidth = 100; }
Bar()方法(编译报错):
void Bar(object sender, EventArgs e) { if ((sender is ComboBox comboBox) == false) return; comboBox.DropDownWidth = 100; }
这事儿得从C#编译器的分支分析逻辑说起。
对于Foo()里的!(sender is ComboBox comboBox)写法,编译器做了特殊的逻辑识别:它能明确判断,当这个条件成立时,方法会直接return退出。那反过来,剩下的代码分支里,sender肯定是成功匹配为ComboBox类型了,comboBox变量也已经完成赋值,所以后续使用它完全没问题。
但到了Bar()里的(sender is ComboBox comboBox) == false这种写法,编译器的分析逻辑就没跟上。它会把(sender is ComboBox comboBox)当成一个独立的布尔表达式,虽然我们人类能看出来这和Foo()里的条件是等价的,但编译器没办法把这个表达式的结果和comboBox变量的赋值状态关联起来。在它的判断里,comboBox有可能还没被赋值,所以当你后面调用comboBox.DropDownWidth的时候,就会触发“Use of unassigned local variable 'comboBox'”的编译错误。
说白了就是,编译器对!(模式匹配)这种语法做了针对性的分支优化,但对(模式匹配) == false这种等价写法,没做同样的推导处理。
内容的提问来源于stack exchange,提问作者brainbolt
相关产品推荐
相关产品推荐

