为何LINQ SQL语法不遵循可空性推断?
问题解析
先看两个C#方法实现:
IEnumerable<T> WhereNotNull<T>(IEnumerable<T?> seq) => from item in seq select item; IEnumerable<T> WhereNotNull2<T>(IEnumerable<T?> seq) => seq.Select(item => item);
其中第一个使用LINQ查询语法的方法不会触发编译器警告,但第二个使用方法链的方法会弹出如下警告:
Nullability of reference types in value of type 'System.Collections.Generic.IEnumerable<T?>' does not match target type 'System.Collections.Generic.IEnumerable<T>'
原因分析
这是C#编译器对LINQ查询语法和方法链语法的类型推断逻辑差异导致的:
- 方法链版本:
seq.Select(item => item)是严格的恒等映射,Select方法的返回类型与输入序列一致,即IEnumerable<T?>,和方法声明的返回类型IEnumerable<T>存在可空性不匹配,编译器会精准识别这个类型矛盾并抛出警告。 - 查询语法版本:编译器在将查询表达式转换为底层方法调用时,会应用特殊的类型推断规则。当查询结果被赋值给
IEnumerable<T>类型时,编译器会隐式忽略元素的可空标识,默认开发者已经确认序列中不存在null值(尽管这个方法实际上没有做任何空值过滤),因此不会触发警告。
简单来说,查询语法的类型推断在该场景下做了“宽松处理”,而方法链则严格遵循可空类型的校验规则。
内容的提问来源于stack exchange,提问作者NickL
相关产品推荐
相关产品推荐

