首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有一种方便的方法来过滤C# 8.0可空引用序列,只保留非空引用?

是否有一种方便的方法来过滤C# 8.0可空引用序列,只保留非空引用?
EN

Stack Overflow用户
提问于 2019-10-14 08:27:36
回答 4查看 1.4K关注 0票数 15

我有这样的代码:

代码语言:javascript
复制
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());

如何以方便的方式编写这段代码:

不存在空性警告,因为IEnumerable<string>.

  • I不需要添加未经检查的非空断言,如item! (因为我希望从编译器的正常检查中受益,而不依赖于我是一个无错误的编码器),因此推断为nonNullItems类型不需要添加运行时检查的非空断言(因为这在代码大小和运行时都是没有意义的开销,

  • 解决方案或编码模式可以更广泛地应用于其他可空引用类型的项序列.

我知道这个解决方案,它利用了C# 8.0编译器中的流敏感类型,但它是.不太漂亮,主要是因为它太长,太吵了:

代码语言:javascript
复制
var notNullItems = items.SelectMany(item => 
    item != null ? new[] { item } : Array.Empty<string>())
);

还有更好的选择吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-10-14 08:56:34

我认为你必须以某种方式帮助编译器。调用.Where()永远不会安全地返回null。也许微软可以添加一些逻辑来确定像你这样的基本场景,但AFAIK目前的情况并非如此。

但是,您可以编写这样一个简单的扩展方法:

代码语言:javascript
复制
public static class Extension
{
    public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> o) where T:class
    {
        return o.Where(x => x != null)!;
    }
}
票数 9
EN

Stack Overflow用户

发布于 2019-10-14 08:37:09

不幸的是,您将不得不告诉编译器,您比编译器更了解这种情况。

原因之一是Where方法没有以一种让编译器理解非空性保证的方式进行注释,实际上也不可能对其进行注释。可能需要在编译器中添加更多的启发式方法来理解一些基本的情况,比如这个,但是目前我们还没有。

因此,一种选择是使用无效的宽恕运算符,俗称“该死的运算符”。然而,您可以亲自讨论这个问题,而不是在使用集合的代码中到处洒上感叹号,相反,您可以在生成集合时增加一个额外的步骤,至少对我来说,这会使它更令人愉快:

代码语言:javascript
复制
var nonNullItems = items.Where(item => item != null).Select(s => s!);

这将将nonNullItems标记为IEnumerable<string>而不是IEnumerable<string?>,因此在其余代码中将正确处理。

票数 9
EN

Stack Overflow用户

发布于 2019-10-22 18:56:22

我不知道这个答案是否符合你的第三个要点的标准,但是你的.Where()过滤器也不满足,所以.

替换

var nonNullItems = items.Where(item => item != null)

使用

var nonNullItems = items.OfType<string>()

这将为IEnumerable<string>生成一种推断类型的nonNullItems,这种技术可以应用于任何可为空的引用类型。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58372791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档