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

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

I have a console app to try out the C# 8 null reference types. Switched the project to build with lang ver C# 8.

Then the following code results in a warning.

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
    }
}

What does this actually mean?

ベストアンサー1

For anyone ending up here. You can put #nullable enable on top of the file for a file-by-file approach as suggested by @Marc in the comments.

You can also use combinations of #nullable enable/disable to annotate just parts of the file

class Program
{
    static void Main(string[] args)
    {
#nullable enable
        string? message = "Hello World";
#nullable disable
        string message2 = null;

        Console.WriteLine(message);
        Console.WriteLine(message2);
    }
}

Here's a link to the docs. https://learn.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.

ファイル内の Nullable 要素を使用して、プロジェクトに対して null 許容注釈コンテキストと null 許容警告コンテキストを設定できます.csproj。この要素は、コンパイラが型の null 許容性を解釈する方法と、生成される警告を構成します。有効な設定は次のとおりです。

  • enable:
    • null 許容注釈コンテキストが有効になっています。null 許容警告コンテキストが有効になっています。
    • stringたとえば、参照型の変数はnull 非許容です。すべての null 許容警告が有効になっています。
  • warnings:
    • null 許容注釈コンテキストは無効です。null 許容警告コンテキストは有効です。
    • 参照型の変数は無視されます。すべての null 可能性の警告が有効になります。
  • annotations:
    • null 許容注釈コンテキストは有効です。null 許容警告コンテキストは無効です。
    • stringたとえば、参照型の変数はnull 非許容です。すべての null 許容警告は無効になります。
  • disable:
    • null 許容注釈コンテキストは無効です。null 許容警告コンテキストは無効です。
    • 参照型の変数は、C# の以前のバージョンと同様に無視されます。すべての null 可能性の警告は無効になります。

ファイルでは.csproj<Nullable>enable</Nullable>関連する<PropertyGroup>要素を追加するだけです (プロジェクト ファイルには<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: null 参照の逆参照の可能性があります。
  • CS8603: null 参照が返される可能性があります。

ディレクティブを使用して、プロジェクト内の任意の場所に同じコンテキストを設定することもできます。

  • #nullable enable: null 許容注釈コンテキストと null 許容警告コンテキストを有効に設定します。
  • #nullable disable: null 許容注釈コンテキストと null 許容警告コンテキストを無効に設定します。
  • #nullable restore: null 許容注釈コンテキストと null 許容警告コンテキストをプロジェクト設定に復元します。
  • #nullable disable warnings: null 許容警告コンテキストを無効に設定します。
  • #nullable enable warnings: null 許容警告コンテキストを有効に設定します。
  • #nullable restore warnings: null 許容警告コンテキストをプロジェクト設定に復元します。
  • #nullable disable annotations: null 許容注釈コンテキストを無効に設定します。
  • #nullable enable annotations: null 許容注釈コンテキストを有効に設定します。
  • #nullable restore annotations: 注釈の警告コンテキストをプロジェクト設定に復元します。

デフォルトでは、null 許容注釈と警告コンテキストは無効になっています。つまり、既存のコードは変更されずにコンパイルされ、新しい警告も生成されません。

なお、C# 8.0 および Visual Studio 2019 のプレリリース バージョンでも がサポートされていましたsafeonlyが、このオプションは削除されており、最終出荷の C# 8.0 には存在しません。また、プレリリース バージョンでは が使用されていました#pragma warning restore nullableが、リリース バージョンでは が使用されます#nullable restore warnings

おすすめ記事