NetFramework では、null代入可能な値型をNullable<>型によって表します。T?と略記することができます
一方、参照型ではもともとnull代入可能なので、逆にnullが代入できないことを表す型がなく、実行時にNullReferenceExceptionが発生して初めてミスに気付くことが度々あります。
これを解決するためC# 8.0ではnull許容参照型
が導入されました。
記法はnull許容値型と同じく、型名の後に?を付けます。
但し、新たに型が追加されたわけではなく、同じ型についてnullが許容されるかどうかを判別する仕組みで動作します。NullReferenceExceptionが発生する可能性があると思われる場所には、コンパイル時に警告が出るようになっています。
1 | namespace NullableReferenceTypeTest |
C# 9.0 では制約がない型引数に ? をつけれるようになりました。
ジェネリックで制約がない型引数を使ってnull許容かどうかにかかわらず使えるクラスを作成する場合、型引数に ? をつけると問題が発生します。
右のコードはこのような場合に余分な警告が発生することを示すものです。
ContainerGetValueTest
では c1 にnull許容しない型Test
を実引数Tに設定しています。
それに対してc2にはnull許容する型Test?
を実引数Tに設定しています。
それぞれGetValue
で値を取得しているのですが、null許容しない型c1を引数に指定した場合は警告が出ます。
#nullable enable
は、以降でnull許容参照型を有効にすることを示しています。
同様に#nullable disable
で無効になり、#nullable restore
で以前の設定に戻ります。
対策としては ! をつけて警告を無視させることも考えられます。
しかし、null許容かどうかにかかわらず使えるクラスの型引数にnull許容参照型を指定することは、上記のあいまいさがあるので、当面これに該当する部分はnull許容参照型を無効のままにしようと考えています。
ジェネリックでない型や、ジェネリックの場合でもnullを許容するかどうか用途が決まっている場合には、null許容参照型を使っていこうと思います。