我有这样的代码:
IEnumerable<string?> items = new [] { "test", null, "this" };
var nonNullItems = items.Where(item => item != null); //inferred as IEnumerable<string?>
var lengths = nonNullItems.Select(item => item.Length); //nullability warning here
Console.WriteLine(lengths.Max());
我怎样才能以方便的方式编写这段代码:
- 没有可空性警告,因为类型
nonNullItems
被推断为IEnumerable<string>
. - 我不需要添加未经检查的不可空性断言,例如
item!
(因为我想从编译器完整性检查中获益,而不是依赖我成为一个无错误的编码员) - 我不添加运行时检查的不可空性断言(因为这在代码大小和运行时都是毫无意义的开销,并且在人为错误失败的情况下比理想情况晚)。
- 该解决方案或编码模式可以更普遍地应用于可空引用类型的其他项目序列。
我知道这个解决方案,它利用了 C# 8.0 编译器中的流敏感类型,但它......不是那么漂亮,主要是因为它太长且嘈杂:
var notNullItems = items.SelectMany(item =>
item != null ? new[] { item } : Array.Empty<string>())
);
有更好的选择吗?
最佳答案
我认为您必须以某种方式帮助编译器。调用 .Where()
永远不会安全地返回 not-null。也许 Microsoft 可以添加一些逻辑来确定像您这样的基本场景,但据我所知,目前情况并非如此。
但是,您可以像这样编写一个简单的扩展方法:
public static class Extension
{
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> o) where T:class
{
return o.Where(x => x != null)!;
}
}
关于c# - 是否有一种方便的方法来过滤一系列 C# 8.0 可空引用,仅保留非空引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58372791/