可为 null 的引用类型的注释只能在“#nullable”上下文中的代码中使用

The annotation for nullable reference types should only be used in code within a '#nullable' context

我有一个控制台应用程序可以试用 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
        }
    }

这到底是什么意思?

致所有来到这里的人。 您可以按照@Marc 在评论中的建议,将 #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);
    }
}

这是文档的 link。 https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts

Nullable contexts enable fine-grained control for how the compiler interprets reference type variables. The nullable annotation context of any given source line is either enabled or disabled. You can think of the pre-C# 8.0 compiler as compiling all your code in a disabled nullable context: any reference type may be null. The nullable warnings context may also be enabled or disabled. The nullable warnings context specifies the warnings generated by the compiler using its flow analysis.

The nullable annotation context and nullable warning context can be set for a project using the Nullable element in your .csproj file. This element configures how the compiler interprets the nullability of types and what warnings are generated. Valid settings are:

  • enable:
    • The nullable annotation context is enabled. The nullable warning context is enabled.
    • Variables of a reference type, string for example, are non-nullable. All nullability warnings are enabled.
  • warnings:
    • The nullable annotation context is disabled. The nullable warning context is enabled.
    • Variables of a reference type are oblivious. All nullability warnings are enabled.
  • annotations:
    • The nullable annotation context is enabled. The nullable warning context is disabled.
    • Variables of a reference type, string for example, are non-nullable. All nullability warnings are disabled.
  • disable:
    • The nullable annotation context is disabled. The nullable warning context is disabled.
    • Variables of a reference type are oblivious, just like earlier versions of C#. All nullability warnings are disabled.

在您的 .csproj 文件中,只需在相关的 <PropertyGroup> 元素中添加 <Nullable>enable</Nullable>(您的项目文件可能对每个项目配置名称都有单独的 <PropertyGroup> 元素)。

所以您的项目文件应该如下所示:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

要将可为 null 的消息显示为错误而不是警告,请将其添加到您的项目文件中:

<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:可能的空引用 return。

You can also use directives to set these same contexts anywhere in your project:

  • #nullable enable: Sets the nullable annotation context and nullable warning context to enabled.
  • #nullable disable: Sets the nullable annotation context and nullable warning context to disabled.
  • #nullable restore: Restores the nullable annotation context and nullable warning context to the project settings.
  • #nullable disable warnings: Set the nullable warning context to disabled.
  • #nullable enable warnings: Set the nullable warning context to enabled.
  • #nullable restore warnings: Restores the nullable warning context to the project settings.
  • #nullable disable annotations: Set the nullable annotation context to disabled.
  • #nullable enable annotations: Set the nullable annotation context to enabled.
  • #nullable restore annotations: Restores the annotation warning context to the project settings.

By default, nullable annotation and warning contexts are disabled. That means that your existing code compiles without changes and without generating any new warnings.

请注意,C# 8.0 和 Visual Studio 2019 的预发布版本也支持 safeonly,但是 this option has since been removed 并且不存在于最终发布的 C# 8.0 中。此外,预发布版本使用 #pragma warning restore nullable 但发布版本使用 #nullable restore warnings.

我也遇到了同样的错误,我花了几天时间解决这个问题,原因在其他答案中没有描述:Roslyn C# 编译器中有特殊的(未记录的?)规则 生成的代码 使用可空功能,直到我将 Visual Studio 2019 升级到最新版本(16.4+),错误消息与上面的无用消息完全相同——尽管有 <Nullable>enabled</Nullable> 在我的项目文件中。

但在 Visual Studio 2019 的最新版本中,他们已将错误消息升级为:

warning CS8669: The annotation for nullable reference types should only be used in code within a ‘#nullable’ annotations context. Auto-generated code requires an explicit ‘#nullable’ directive in source.

(在错误信息的新增部分加了重点。)

因此,如果您在发送的任何 .generated.cs 文件中看到此错误消息,则需要向这些文件添加 #nullable enable 明确地 — Roslyn 显然总是忽略生成代码的项目级 <Nullable>enable</Nullable> 设置。