C# 8.0のNull許容参照型を有効にする
先日 .NET Core 3.0 がリリースされ、同時に C# 8.0 もリリースされました。色々と先行き不安なところはありつつも、C# 8.0 最大の変更点は参照型が null なり得るかどうかをコード上で明示できる Null許容参照型 の機能でしょう。 Kotlin や TypeScript など、他の言語には既に存在する機能です。また ReSharper が導入された Visual Studio や Rider では JetBrains Annotation を使用することで擬似的ではありますが、非nullを明示することができました。
今回は機能を有効にしたときの文法ではなく、そもそも機能を有効にする方法をメモします。2019年10月現在、Null許容参照型機能を Visual Studio の設定画面から有効にすることはできません。
部分的に有効にする
Null許容参照型を特定のファイルや行に対して有効にするには、 #nullable
ディレクティブを使用します。取り得る値は enable
disable
restore
の3つです。
値 | 効果 |
---|---|
enable | このディレクティブ以降、Null許容参照型の機能を有効に変更します。 |
disable | このディレクティブ以降、Null許容参照型の機能を無効に変更します。 |
restore | このディレクティブ以降、Null許容参照型の機能をプロジェクトのデフォルト値に変更します。 |
class Program { static void Main(string[] args) { // これ以降Null許容参照型 ON #nullable enable string? nullable = null; if (nullable?.Length == 0) { Console.WriteLine("never"); } } }
プロジェクト全体に対して有効にする
プロジェクト全体に対して有効に設定するには csproj の <PropertyGroup>
に <Nullable>
タグを追加します。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <LangVersion>8.0</LangVersion> <!-- プロジェクト全体を有効に設定 --> <Nullable>enable</Nullable> </PropertyGroup> </Project>
Null許容参照型の適用種類
Null許容参照型には2つのコンテキストが存在します。1つは文法の有効可否です。 #nullable enable annotations
を付与することでNull許容参照型の文法のみを有効にすることができます。もう1つが警告の出力有無です。こちらは #nullable enable warnings
とすることでコンパイラーが分かる範囲で警告を出力してくれます。
警告のみ有効の場合
class Program { static void Main(string[] args) { #nullable enable warnings string nullable = null; if (nullable.Length == 0) // 警告 CS8602 null 参照の可能性があるものの逆参照です。 { Console.WriteLine("never"); } } }
文法のみ有効の場合
class Program { static void Main(string[] args) { #nullable enable annotations string nullable = null; if (nullable.Length == 0) // 特に警告は出ないがここでNullReferenceException { Console.WriteLine("never"); } } }
文法、警告共に有効の場合
class Program { static void Main(string[] args) { #nullable enable string nullable = null; // 警告 CS8600 Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。 if (nullable.Length == 0) // 警告 CS8602 null 参照の可能性があるものの逆参照です。 { Console.WriteLine("never"); } } }