如何为整个项目启用 C# 8.0 的 Nullable Reference Types 功能

Posted

技术标签:

【中文标题】如何为整个项目启用 C# 8.0 的 Nullable Reference Types 功能【英文标题】:How to enable Nullable Reference Types feature of C# 8.0 for the whole project 【发布时间】:2019-05-07 02:17:32 【问题描述】:

根据C# 8 announcement video,可以为整个项目启用“可空引用类型”功能。

但是如何为项目启用它呢?我在 Visual Studio 2019 Preview 1 的“项目属性”窗口中没有找到任何新的合适选项。

如果 C# 语言版本更改为 8.0,是否可以为 'legacy' .csproj 项目启用?

【问题讨论】:

【参考方案1】:

在 Visual Studio 16.2(从预览版 1 开始)中,属性名称更改为 Nullable,这样更简单,并且与命令行参数一致。

将以下属性添加到您的 .csproj 文件中。

<PropertyGroup>
  <Nullable>enable</Nullable>
  <LangVersion>8.0</LangVersion>
</PropertyGroup>

如果您的目标是 netcoreapp3.0 或更高版本,则无需指定 LangVersion 即可启用可为空的引用类型。


对于旧版 Visual Studio:

从 16.0 预览 2 到 16.1,将 NullableContextOptions 设置为 enable。 在 16.0 预览版 1 中,将 NullableReferenceTypes 设置为 true

【讨论】:

我刚刚在 VS 2019/16.1.1 上尝试过这个,但它似乎没有做任何事情。为了测试它,我在其中一个类中添加了#nullable enable,然后我可以看到有关空对象的警告。 @LarrySmith 抱歉,此更改是在 16.2P1 中进行的。我已经更新了我的答案。在 16.1.1 中,您仍然需要 NullableContextOptions 请注意,布尔逻辑可能有点不直观:enable 表示“启用新的 C# 8.0 设置,其中默认类型不可为空”。 disable 的意思是“按照旧的方式进行,每种类型都可以为空。” 我还必须在 之前从旧的“15,0”更新 16.0处理较旧的非 SDK 项目,即使它们已通过 VS 16.3 RTM 的属性 GUI 正确升级到框架 4.8。仅尊重 C#8 语言版本,无需任何额外的项目文件编辑。 @TonyWall 我很好奇你为什么需要它。我刚刚在 VS 16.3.7(即非 SDK 样式项目)中创建了一个新的 .NET Framework 控制台应用程序,将 LangVersionNullable 属性添加到 .csproj 并且它工作正常。该项目也有ToolsVersion="15.0"【参考方案2】:

请注意,此设置在 VS 2019 预览版 1 和预览版 2 之间进行了更改。对于预览版 2 或 3,您需要在 .csproj 中使用此设置:

<PropertyGroup>
  <LangVersion>8.0</LangVersion>
  <NullableContextOptions>enable</NullableContextOptions>
</PropertyGroup>

之前的答案中提到的&lt;NullableReferenceTypes&gt;(当我最初在 2019 年 2 月 4 日写这个答案时,它已被标记为已接受的答案)在写答案时是正确的,但它不再被识别.

【讨论】:

有关此选项可用值的更多信息(enabledisablesafeonly 等):github.com/dotnet/roslyn/blob/master/docs/features/… 这在最近的版本中再次改变了吗?这在 Preview 4.2 中似乎对我不起作用 由于 Visual Studio 6.2 已被简化为 (请参阅接受的答案)【参考方案3】:

除了@DrewNoakes 接受的答案之外,请注意,可以通过在包含您的.sln 文件的文件夹中添加一个名为Directory.Build.props 的文件来为所有项目一次设置可为空属性。

只需像这样定义您的 Directory.Build.props 文件:

<Project>

  <PropertyGroup>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

您需要重新启动 Visual Studio 才能使其生效。

更多关于Directory.Build.props

【讨论】:

【参考方案4】:

值得注意的是,到目前为止,这也是项目“属性”页面中的公开设置:

至少在 VS2019 16.6+ 中。

【讨论】:

但不适用于旧式 csproj。 我没有看到那个选项。【参考方案5】:

对于 Visual Studio 2019 Preview 2 和 3,请参阅 Ian Griffiths's answer。

Visual Studio 2019 解决方案Preview 1

要为 .NET Core 项目启用可空引用类型功能,请将 NullableReferenceTypes 属性添加到 .csproj 文件,如下所示:

<PropertyGroup>
  ...
  <NullableReferenceTypes>true</NullableReferenceTypes>
  <LangVersion>8.0</LangVersion>
</PropertyGroup>

正如 @JulienCouvreur 在 cmets 中提到的关于 https://github.com/dotnet/project-system/issues/4058 的那样,“旧”项目系统尚不支持新属性,但将在 C# 8.0 发布之前支持。

【讨论】:

您是否尝试将目标框架更改为net472?顺便说一句,您是如何/在哪里找到该设置的?该参考将非常有用。我发现很多事情并不像视频所示的那样有效 @PanagiotisKanavos,该标签是我在原始问题中链接的视频的作者 Mads Torgersen 在 YouTube 上的 cmets 中提出的 “旧”项目尚不支持此属性。问题由github.com/dotnet/project-system/issues/4058 跟踪 仍然没有任何反应。【参考方案6】:

旧版 csproj 格式

您询问了旧版.csproj 格式。在文本编辑器中打开项目文件并进行以下更改:

    DebugRelease PropertyGroup 部分中添加/更改&lt;LangVersion&gt;8.0&lt;/LangVersion&gt;

     <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <LangVersion>preview</LangVersion>
    

    通过将&lt;Nullable&gt;enable&lt;/Nullable&gt; 添加到主PropertyGroup 来启用对可空引用类型的支持:

     <PropertyGroup>
        <Nullable>enable</Nullable>
    

在 Visual Studio 2019 v16.2.0 Preview 3 中使用 C# 8 和可为空的引用类型语法在 .NET WinForms 应用中进行测试。


SDK 风格的项目文件

SDK 风格的项目要简单得多,并且可以在 Visual Studio 中进行编辑。对于这些,您只需要(在同一 PropertyGroupTargetFrameworkTargetFrameworks 中):

  <PropertyGroup>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
  </PropertyGroup>

注意事项

.NET Core 3.x 项目以 C# 8 by default 为目标,因此您无需为这些项目指定 LangVersion

.NET Framework 项目的默认值为 C# 7.3,即使使用 &lt;LangVersion&gt;latest&lt;/LangVersion&gt;,您也不会获得 C# 8.0。您必须将语言版本显式设置为 8.0。详情请参考我对问题Does C# 8 support the .NET Framework?的回答。

【讨论】:

不,还是什么都没有。

以上是关于如何为整个项目启用 C# 8.0 的 Nullable Reference Types 功能的主要内容,如果未能解决你的问题,请参考以下文章

如何为整个 c# 应用程序设置默认文化信息

如何为 IntelliJ IDEA 项目禁用或启用 Gradle / Maven 自动导入?

如何为 C# 项目生成 .tlh 文件

如何为测试目的模拟网络故障(在 C# 中)?

在 VSCode 中,如何为没有 package.json 的项目启用 Angular/Backbone/jQuery 智能感知?

如何为 ASP.NET Core 2.2 项目中的子域正确启用 CORS?