c# - 是否有一种方便的方法来过滤一系列 C# 8.0 可空引用,仅保留非空引用?

标签 c# nullable nullable-reference-types

我有这样的代码:

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/

相关文章:

c# - 使用 NetworkStream.BeginRead 和 NetworkStream.EndRead 实现超时

c# - 如何避免不相关的可空警告(没有显式抑制)

c# - 具有泛型返回类型的可空引用类型

entity-framework - 是否可以选择使 Entity Framework 将空字符串恢复为 null?

c# - 与 IComparable 一起使用的可空泛型类型。可能吗?

c# - 可空引用类型 : "Try" method pattern, 在返回 false 时收到 null 警告

c# - .NET - 哪些系统程序集被注释为可空引用类型?

c# - 为什么编译器不喜欢隐式转换为 uint?

c# - 为什么var不能应用于成员变量

c# - 如何混淆字符串常量?