未从 FirstOrDefault 公开的可空引用类型信息

Posted

技术标签:

【中文标题】未从 FirstOrDefault 公开的可空引用类型信息【英文标题】:Nullable reference type information not exposed from FirstOrDefault 【发布时间】:2020-02-28 10:34:04 【问题描述】:

我想测试 C# 8.0 中的新 nullable reference types 功能。

我开始了一个针对 .NET Core 3.0 的新项目,在 .csproj 文件中启用了可为空的引用类型,然后开始编码。我创建了一个简单的列表,它采用string[] 并在等于abc 的数组中返回string。现在,因为我不确定abc 是否确实存在于数组中,所以我使用FirstOrDefault(),如果找不到匹配项,则默认为null

using System;
using System.Linq;

public string FindArgument(string[] args)

    var arg = args.FirstOrDefault(x => x == "abc");
    return arg;

我的方法返回string,它应该现在是non-nullable类型。由于FirstOrDefault() 可能返回null,我希望上述方法在返回可能为空arg 变量时会产生警告。它没有。

查看 Visual Studio 中 FirstOrDefault() 的签名,很清楚为什么:该方法返回 string,而不是我期望的可空等效 string?

使用下面的方法体确实会产生我预期的警告:

var arg = args.Contains("abc") ? "abc" : null;
return arg;

系统库(在此示例中为 System.Linq)在面向 .NET Core 3.0 时真的不公开可空性信息吗?

【问题讨论】:

【参考方案1】:

看起来 System.Linq 在 3.0 版本中不能为空注释。所以 Nullable Reference Types 不会发出正确的警告。

您可以在roslyn repo 中查看类似问题。 This open issue on Github 与您的问题非常相似。在那个问题中,一位贡献者解释了当前的问题:

System.Linq 在 corefx 的 ma​​ster 分支中可以为 null 注释,但在 release/3.0 中不是。所以编译器没有什么意外的。 编译器应该提供一些诊断信息,表明您正在使用可以为空的东西。

【讨论】:

要添加此内容,您可以使用this package 今天获取正确的注释。 在 .NET Core 3.1 中仍然如此。它使使用可为空的引用类型变得不那么好。我相信拉取请求 corefx/pull/40651 解决了这个问题,但显然我们必须等到 .NET 5 才能得到它:-( 肮脏的工作......选择您的项目,强制转换为可为空的类型。 Re-shaper 抱怨它的冗余,但确实有效。 var nullableMatch = collection.Select(x => (MyType?) x).FirstOrDefault(x => x.Field == value);

以上是关于未从 FirstOrDefault 公开的可空引用类型信息的主要内容,如果未能解决你的问题,请参考以下文章

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

使用 C# 8 的可空引用类型

.NET Framework 项目中的可空引用类型不能与 IntelliSense 一起使用

将可空引用类型转换为不可空引用类型,不那么冗长

何时在启用可空引用类型的情况下对参数进行空检查

嵌套js代码中可空值的可空数组首先graphql