ということを確認した。
成果物
nullコンテキスト
コンテキスト設定
設定方法 | コンテキスト | null許容 | |
---|---|---|---|
<Nullable> | 注釈 | 警告 | 参照型 |
enable | ○ | ○ | 非 |
warnings | ☓ | ○ | 無 |
annotations | ○ | ☓ | 非 |
disable | ☓ | ☓ | 無 |
設定方法 | コンテキスト | |
---|---|---|
#nullable | 注釈 | 警告 |
enable | ○ | ○ |
disable | ☓ | ☓ |
restore | pj | pj |
enable warnings | − | ○ |
disable warnings | − | ☓ |
restore warnings | − | pj |
enable annotations | ○ | − |
disable annotations | ☓ | − |
restore annotations | pj | − |
公式によるとrestore
は「プロジェクト設定に戻す」らしいが、ここでは「1つ前の設定に戻す」とある。どっちだよ。
以下、設定例。
.csproj
<Nullable>enable<Nullable>
.cs
#nullable enable ... #nullable disable
プロジェクト作成
dotnet new console -o NullableDirective cd NullableDirective
.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> </Project>
プロジェクト生成したときのままで変更なし。<Nullable>
の追加もせず。
コード
Program.cs
new Enable().Run(); new Disable().Run(); new Restore().Run();
Enable.cs
class Enable { public void Run() { #nullable enable int i1 = null; // error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません int? i2 = null; string s1 = null; // warning CS8600: Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。 string? s2 = null; string s3 = null!; Console.WriteLine($"{i1}, {i2}, {s1}, {s2}, {s3}"); } }
Disable.cs
class Disable { public void Run() { #nullable disable int i1 = null; // error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません int? i2 = null; string s1 = null; string? s2 = null; // warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。 Console.WriteLine($"{i1}, {i2}, {s1}, {s2}"); } }
Restore.cs
class Restore { public void Run() { #nullable restore int i1 = null; int? i2 = null; string s1 = null; string? s2 = null; Console.WriteLine($"{i1}, {i2}, {s1}, {s2}"); } }
実行結果
$ dotnet run Enable.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] Enable.cs(12,25): warning CS8600: Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。 [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] Restore.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] Restore.cs(13,19): warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。 [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] Disable.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] Disable.cs(13,19): warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。 [/tmp/work/CSharp.Tutorial.Nullable.Directive.20191030134014/src/NullableDirective/NullableDirective.csproj] ビルドに失敗しました。ビルド エラーを修正して、もう一度実行してください。
以下のコンパイルエラーに関しては共通だった。
int i1 = null;
Restore.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません Enable.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません Disable.cs(10,22): error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません
Restore
の結果はDisable
と同じだった。
Enable.cs
null許容型に対する警告なし
参照型でnull許容したいときは#nullable enable
すると警告なく書けるようだ。
.csprojに<Nullable>
を設定しなくても#nullable enable
ディレクティブ範囲内なら以下CS8632
警告が出ない。
warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。
string? s2 = null;
#nullable enable
にする- 参照型をnull許容型にする
- 警告
CS8632
が出ない
- 警告
- 参照型をnull許容型にする
null非許容型に対する警告あり
null非許容のときにnull
が代入されたらCS8600
警告が出る。
Enable.cs(12,25): warning CS8600: Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。
string s1 = null;
null免除演算子!
で警告回避
上記コードのnull
に!
を追加すればCS8600
警告を回避できる。つまり、null非許容型にnull!
を代入しても警告が出ない。null
だと出る。
string s1 = null!; // 警告CS8600なし
Restore.cs
#nullable restore
はプロジェクト設定に戻す
前回、#nullable restore
の効果がわからなかった。公式によると「プロジェクト設定に戻す」らしいが、ここでは「1つ前の設定に戻す」とある。どっちかわからなかった。
今回試してみたところ、Restore
はプロジェクト設定に戻すものだと思われる。
前提条件は以下。
- プロジェクトは
<Nullable>
未設定のため#nullable disable
と同様のはず - 今回のコードにおいて
enable
,disable
,restore
の順に実行した
Restore
時点ではその直前にあたる#nullable disable
の状態なはず。それの1つ前だと#nullable enable
である。つまり、1つ前ならEnable
実行結果と同じになるはず。だが、実際にはDisable
実行結果と同じになった。
プロジェクト設定は<Nullable>
未設定のため#nullable disable
と同様のはずである。これが実際の結果と一致した。
つまり、#nullable restore
の意味は公式通り、「プロジェクト設定に戻す」という意味なのだろう。
あースッキリした。
検証ログ抜粋
Restore.cs(13,19): warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。 Disable.cs(13,19): warning CS8632: '#nullable' 注釈コンテキスト内のコードでのみ、Null 許容参照型の注釈を使用する必要があります。
各ソースコードにおける13行目は以下。
string? s2 = null;
同一コードだが、Enable.cs
では警告が出ていない。なのにDisable.cs
とRestore.cs
は出ている。つまりそれらは同じ動作をしたということだろう。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux