【C#】nullableの挙動を確認する
int? nullable; int nonNullable;
とりあえずこんな感じの変数を使います
代入
nonNullable = 10; nullable = nonNullable; nullable = 20; nonNullable = nullable; //←コンパイルエラー nonNullable = (int)nullable; nullable = null; nonNullable = (int) nullable; //←System.InvalidOperationException
null非許容型からnull許容型への代入:問題なし
null許容型からnull非許容型への代入:キャストが必要
みたいですね
ちなみにnull許容型からnull非許容型へのキャスト時にはちゃんと値が入ってないとExceptionでるのでちゃんとnullチェックするとか??演算子使うとかしましょう
関数
オーバロード
static void Func(int? arg) { Console.WriteLine("Func-nullable"); } static void Func(int arg) { Console.WriteLine("Func-nonNullable"); }
こんな感じの関数の定義は問題なくできました
実際にこの関数を呼んだ時の動作ですが
nullable = nonNullable = 10; Func(nullable); //Func-nullable Func(nonNullable); //Func-nonNullable Func((int?)nonNullable); //Func-nullable Func((int)nullable); //Func-nonNullable
コメントで記述しているように、int?型とint型は別の型と認識されて関数が呼ばれています
キャストすれば型が変わったものと認識されるようです(当たり前か)
別の関数は呼べるのか
関数定義を変更しました
static void Func_Nullable(int? arg) { Console.WriteLine("Func_Nullable"); } static void Func_NonNullable(int arg) { Console.WriteLine("Func_NonNullable"); }
そして呼び出し側ですが
nullable = nonNullable = 10; Func_Nullable(nonNullable); Func_NonNullable(nullable); //←コンパイルエラー
nullable型の関数にnonNullableを渡すのは問題ないようです
ただ逆はエラーですね キャストしましょう
拡張関数
オーバロード
static class Extensions { public static void ExFunc(this int? arg) { Console.WriteLine("ExFunc-nullable"); } public static void ExFunc(this int arg) { Console.WriteLine("ExFunc-nonNullable"); } }
定義は問題なくできました
そしてこれを呼び出します
nullable = nonNullable = 10; nullable.ExFunc(); //ExFunc-nullable nonNullable.ExFunc(); //ExFunc-nonNullable ((int?)nonNullable).ExFunc(); //ExFunc-nullable ((int)nullable).ExFunc(); //ExFunc-nonNullable nullable?.ExFunc(); //ExFunc-nonNullable ☆ nullable = null; nullable.ExFunc(); //ExFunc-nullable nullable?.ExFunc(); //←関数が呼ばれない ☆
注目すべきは☆マークのある2つですね
nullable
がnull
でないときはint型の関数が呼ばれ、null
のときは関数が呼び出されません
この動作は拡張関数でも使えるようです
まとめ
- キャストすればなんとかなる
null許容型変数?.関数名()
の構文は拡張関数でも使える
(実は確認したかったのは拡張関数の挙動だけだったりする)
以上