null許容型の変数や値をnull非許容型に代入する

null許容型の変数や値をnull非許容型に代入するコードを紹介します。

コードの確認

次のコードを記述します。
    private void button1_Click(object sender, EventArgs e)
    {
      int? Value1;
      Value1 = 156;
      int Value2 = Value1;
      textBox1.Text += Value2.ToString();
    }

ビルドするとエラーが発生します。エラーメッセージは次の通りです。
エラーメッセージ
CS0266: 型 'int?' を 'int' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)

対処法1:キャストする

ヌル非許容型への型キャストのコードを追記するとコンパイルエラーを解消できます。 下記のコードに変更してコンパイルをします。
    private void button1_Click(object sender, EventArgs e)
    {
      int? Value1;
      Value1 = 156;
      int Value2 = (int)Value1;
      textBox1.Text += Value2.ToString();
    }

この方法では、コンパイルは通りますが、Value1の値がnullになる場合は、アプリケーションは例外が発生します。また、ビルド時にワーニングも発生します。
    private void button1_Click(object sender, EventArgs e)
    {
      int? Value1;
      Value1 = null;
      int Value2 = (int)Value1; //ここで例外発生
      textBox1.Text += Value2.ToString();
    }
ワーニングメッセージ
CS8629:Null 許容値型は Null になる場合があります。

対処法2:if文で場合分けする

例外を発生させたくない場合は、if文で場合分けして、nullの場合は別の値を代入する方法があります。 Value1変数の値がnullであった場合は、Value1の値をValue2変数に代入せずに、別の値をValue2に代入します。
このコードの場合はValue1がnullであった場合でも例外は発生しません。
    private void button2_Click(object sender, EventArgs e)
    {
      int? Value1;
      Value1 = null;
      int Value2;
      if (Value1 is null) Value2 = -1; else Value2 = (int)Value1;
      textBox1.Text += Value2.ToString();
    }

対処法3:??演算子を利用

if文による場合分けと同様の処理になりますが、??演算子を利用するとシンプルに記述できます。
??演算子の詳細はこちらの記事を参照してください。
    private void button2_Click(object sender, EventArgs e)
    {
      int? Value1;
      Value1 = null;
      int Value2 = Value1 ?? 0;
      textBox1.Text += Value2.ToString();
    }

具体例: System.IO.Path.GetDirectoryName の例

具体例を紹介します。
.NET6 のWindows Formアプリケーションで以下のコードを記述します。
    private void button4_Click(object sender, EventArgs e)
    {
      string dirname = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
      textBox1.Text += dirname;
    }

ビルドするとワーニングが発生します。ワーニングのメッセージは次の通りです。
ワーニングメッセージ
CS8600: Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。



GetDirectoryName()の戻り値の型は string? であり、string 型の変数に代入する場合、nullを代入してしまう可能性があるため、アラートが発生します。
対処法は先に紹介した方法を利用して、以下のコードに変更します。
??演算子を利用し、GetDirectoryName() メソッドの戻り値が null であった場合 dirname 変数には空文字を代入する処理にします。
private void button4_Click(object sender, EventArgs e)
{
    string dirname = System.IO.Path.GetDirectoryName(Application.ExecutablePath) ?? "";
    textBox1.Text += dirname;
}

コードを修正すると、アラートが解消されることが確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2022-01-31
iPentec all rights reserverd.