为什么new Foo()==null不会触发VS Code「表达式结果恒为false」警告
两类比较场景的编译器判定逻辑差异
这两个对比场景的本质区别在于C#对值类型、引用类型相等比较的约束不同,静态分析工具的判定逻辑自然有差异:
true == null的判定逻辑:true是值类型bool的非空值,和null比较时,编译器会先将bool隐式提升为可空值类型bool?。根据C#语言规范,非空的可空值类型和null做相等比较的结果恒为false,这个逻辑不存在任何例外,静态分析工具可以100%确定结果,因此会直接弹出恒假警告。new Foo() == null的判定逻辑:Foo是引用类型,C#支持引用类型自定义重载==运算符,编译器无法默认判断你是否为Foo重载了自定义的相等逻辑,自然不能100%确定new Foo() == null的结果一定为false,因此不会触发同类警告。
验证示例
你可以通过自定义==运算符重载验证这个逻辑,以下代码运行时new Foo() == null就会返回true:
class Foo { // 自定义重载==运算符 public static bool operator ==(Foo left, Foo right) { return true; } public static bool operator !=(Foo left, Foo right) { return !(left == right); } // 配套重写Equals、GetHashCode的逻辑此处省略 }
如果你给Foo添加sealed修饰符,并且明确没有重载==运算符,部分版本的Roslyn静态分析工具就会对new Foo() == null触发恒假警告,符合你预期的判定逻辑。
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

