为何C#无法识别引用类型变量已被确保赋值?
可空引用类型警告差异的原因分析
先看你提供的代码:
private TestClass? getTestClass() { return new TestClass(); } private void testMethod() { var testClass = getTestClass(); var testBool = true; if (testBool) { testClass = new TestClass(); } var someInt = testClass.IntMember; }
出现这种差异的核心原因是C#的可空引用类型检查是静态编译期分析,不会追踪变量的运行时确定性值:
- 当你直接写
if (true)时,编译器能立刻识别这是一个编译期常量表达式,明确判定这个分支100%会执行,因此可以确定testClass在分支后已被赋值为非空引用,不会触发警告。 - 而
var testBool = true;声明的是一个普通布尔变量,哪怕你初始化时给了true值,编译器默认假设变量的值有可能在后续代码中被修改(哪怕你当前代码里没写修改逻辑),所以它无法确定这个if分支一定会执行,也就无法保证testClass已经被重新赋值为非空,因此触发了“可能为空的引用的取消引用”警告。
如果要让编译器识别这个变量的常量属性,只需要把testBool声明为常量即可:
const bool testBool = true;
这样编译器就会把它当作编译期常量处理,和直接写if (true)的效果完全一致,不会再触发警告。
内容的提问来源于stack exchange,提问作者Jez
相关产品推荐
相关产品推荐

