可空引用类型的注释只能在“#nullable”上下文中的代码中使用
Posted
技术标签:
【中文标题】可空引用类型的注释只能在“#nullable”上下文中的代码中使用【英文标题】:The annotation for nullable reference types should only be used in code within a '#nullable' context 【发布时间】:2019-08-24 19:24:59 【问题描述】:我有一个控制台应用程序来试用 C# 8 空引用类型。将项目切换为使用 lang ver C# 8 构建。
那么下面的代码会产生一个警告。
class Program
static void Main(string[] args)
string? message = "Hello World";
string message2 = null;
Console.WriteLine(message);
Console.WriteLine(message2);
// The annotation for nullable reference types should only be used in code within a '#nullable' context
这究竟是什么意思?
【问题讨论】:
【参考方案1】:对于任何在这里结束的人。
您可以按照@Marc 在 cmets 中的建议,将#nullable enable
放在文件顶部,以实现逐个文件的方法。
您还可以使用#nullable enable/disable 的组合来仅注释文件的某些部分
class Program
static void Main(string[] args)
#nullable enable
string? message = "Hello World";
#nullable disable
string message2 = null;
Console.WriteLine(message);
Console.WriteLine(message2);
这是文档的链接。 https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts
可空上下文支持对编译器解释引用类型变量的方式进行细粒度控制。任何给定源代码行的 可为空的注释上下文 被启用或禁用。您可以将 C# 8.0 之前的编译器视为在禁用的可空上下文中编译所有代码:任何引用类型都可能为空。 可为空的警告上下文 也可以启用或禁用。可为空的警告上下文指定编译器使用其流分析生成的警告。
可以使用
.csproj
文件中的 Nullable 元素为项目设置可为空的注释上下文和可为空的警告上下文。此元素配置编译器如何解释类型的可空性以及生成哪些警告。有效设置为:enable
: 可空注释上下文已启用。可空警告上下文已启用。 引用类型的变量,例如string
,是不可为空的。所有可空性警告均已启用。warnings
: 可空注释上下文已禁用。可空警告上下文已启用。 引用类型的变量是不经意的。所有可空性警告均已启用。annotations
: 可空注释上下文已启用。可空警告上下文已禁用。 引用类型的变量,例如string
,是不可为空的。所有可空性警告均已禁用。disable
: 可空注释上下文已禁用。可空警告上下文已禁用。 引用类型的变量是无意识的,就像 C# 的早期版本一样。所有可空性警告均已禁用。
在您的.csproj
文件中,只需在相关的<PropertyGroup>
元素中添加<Nullable>enable</Nullable>
(您的项目文件可能为每个项目配置名称具有单独的<PropertyGroup>
元素)。
所以你的项目文件应该是这样的:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
要将可为空的消息显示为错误而不是警告,请将其添加到您的项目文件中:
<WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
...像这样:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
</PropertyGroup>
</Project>
对应的完整消息是:
CS8600:将 null 文字或可能的 null 值转换为不可为 null 的类型。 CS8602:可能取消引用空引用。 CS8603:可能返回空引用。您还可以使用指令在项目的任何位置设置这些相同的上下文:
#nullable enable
:将可空注释上下文和可空警告上下文设置为启用。#nullable disable
:将可空注释上下文和可空警告上下文设置为禁用。#nullable restore
:将可为空的注释上下文和可为空的警告上下文恢复到项目设置中。#nullable disable warnings
:将可为空的警告上下文设置为禁用。#nullable enable warnings
:将可为空的警告上下文设置为启用。#nullable restore warnings
:将可为空的警告上下文恢复到项目设置。#nullable disable annotations
:将可为空的注释上下文设置为禁用。#nullable enable annotations
:将可空注释上下文设置为启用。#nullable restore annotations
:将注释警告上下文恢复到项目设置中。默认情况下,可为空的注释和警告上下文被禁用。这意味着您现有的代码无需更改且不会生成任何新警告即可编译。
请注意,C# 8.0 和 Visual Studio 2019 的预发布版本也支持 safeonly
,但 this option has since been removed 并不存在于最终发布的 C# 8.0 中。此外,预发布版本使用#pragma warning restore nullable
,但发布版本使用#nullable restore warnings
。
【讨论】:
不错的答案;我喜欢它涵盖两种方法 可能还值得扩展以涵盖#nullable disable
和 #nullable restore
或指向涵盖所有这些的文档的链接。
答案已编辑以反映在 VS 16.1 中将属性 NullableContextOptions
重命名为 Nullable
。
好答案。但由于某种原因,改变项目参数的方法对我不起作用。使用 Visual Studio 代码。
我的 csproj 中有这个,所以我不需要在代码中添加任何额外内容 我也遇到了同样的错误,我花了几天的时间来解决它,原因没有在其他答案中描述:Roslyn C# 编译器中有特殊的(未记录的?)规则用于生成的代码 em> 使用可空功能,并且在我将 Visual Studio 2019 升级到最新版本(16.4+)之前,错误消息与上面的无用消息完全相同——尽管我的项目文件中有 <Nullable>enabled</Nullable>
。
但在最新版本的 Visual Studio 2019 中,他们已将错误消息升级为:
警告 CS8669:可空引用类型的注释只能在“#nullable”注释上下文中的代码中使用。 自动生成的代码在源代码中需要一个明确的“#nullable”指令。
(强调添加到错误消息的新添加部分。)
因此,如果您在发出的任何 .generated.cs
文件中看到此错误消息,则需要在这些文件中添加 #nullable enable
明确 - Roslyn 显然总是忽略该项目 -生成代码的级别<Nullable>enable</Nullable>
设置。
【讨论】:
C# 生成文件的可为空上下文的文档位于docs.microsoft.com/en-us/dotnet/csharp/… 下。他们添加了一个“重要”小节,列出了文件被标记为已生成的 4 种方式。 感谢您的链接,这是一个很好的发现!他们终于添加了文档,这很好。但很糟糕的是,这是几年前完全没有记录的“魔法”规则。 即使在新创建的 .NET 6.0 项目、自己的代码、不使用 C#8 可空引用类型的旧解决方案中,我也收到了 CS8632 警告。新项目设置了<Nullable>enable</Nullable>
。解决方案:删除解决方案中的所有bin和obj目录,同样建议MS迁移net6。在我的情况下,“清洁解决方案”是不够的。以上是关于可空引用类型的注释只能在“#nullable”上下文中的代码中使用的主要内容,如果未能解决你的问题,请参考以下文章