开启可空引用类型后Nullable<T>操作触发警告,有哪些更优解决方案?
解决方案
以下是完全符合可空类型规范、无需使用!null宽恕运算符的实现方案:
- 使用
OfType<T>(最简原生方案)OfType<int>()会自动过滤序列中的null值,同时直接转换为非可空的int类型,无需额外编写过滤和取值逻辑,语义清晰且无编译器警告:
var nullableItems = new List<int?>(); var actualNonNullValues = nullableItems.OfType<int>().ToList();
- 自定义
WhereNotNull扩展方法(最优复用方案)
如果项目中这类空值过滤场景较多,可以封装通用扩展方法,统一处理可空值类型和可空引用类型的空值过滤逻辑,性能无额外损耗,可读性更高:
public static class EnumerableExtensions { // 适配可空值类型 public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source) where T : struct { foreach (var item in source) { if (item.HasValue) yield return item.Value; } } // 适配可空引用类型 public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source) where T : class { foreach (var item in source) { if (item is not null) yield return item; } } }
调用方式:
var actualNonNullValues = nullableItems.WhereNotNull().ToList();
- 使用.NET 7+ 内置
Choose方法
如果你使用的是.NET 7及以上版本,可以直接使用框架原生提供的Choose方法,该方法会自动过滤映射后的null值并返回非可空类型:
var actualNonNullValues = nullableItems.Choose(x => x).ToList();
原代码触发警告的原因:LINQ的
Where方法签名没有携带过滤规则的可空性元数据,编译器静态流分析无法跨方法追踪到经过Where(x => x.HasValue)过滤后的元素一定不为null,因此会触发可空性警告。
内容的提问来源于stack exchange,提问作者nvoigt
相关产品推荐
相关产品推荐

