BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース C#の機能: Null許容参照型

C#の機能: Null許容参照型

原文(投稿日:2017/04/17)へのリンク

いや、見出しはタイプミスではない。C#の新しい提案のひとつは、既定で全ての参照型変数をNull非許容型とみなすというものだ。この新しい文法のもとでは、値型と同様に、参照型変数がNull許容であることを明示的に指定する必要がある。

値型と同様に、TはNull非許容型を表し、T?はNull許容型を表す。以下の状況では警告が生成される。

  • Null許容の変数がデリファレンスされていない
  • Null許容の変数やパラメーターがNull非許容の変数に割り当てられている
  • T?[]からT[]にキャストしている
  • T[]からT?[]にキャストしている
  • NullリテラルをNull非許容の変数やパラメーターに割り当てている
  • コンストラクタが全てのNull非許容のフィールドに値を割り当てていない

初めの2つのケースでは、bang演算子(x!)を使用するか、Nullチェックが行われていることをコンパイラが証明できれば、警告は除去される。

実装の詳細

低レベルのコンパイラはnullabilityアノテーションを無視するため問題とはならない。しかしアセンプリレベルにおいては、ライブラリがnullabilityアノテーションが有効な状態でコンパイルされたことを示すような、何らかのマーカーが必要となるだろう。

このnullabilityは技術的に破壊的変更であるため、現在は次のカテゴリーについて開発者にオプトインを許可することが計画されている。

  • Null許容の警告
  • Null非許容の警告
  • 他のファイルのアノテーションによる警告/li>

提案は次のように続く。

オプトインの粒度は、アナライザー式のモデルを提案する。ここではコードの列がプラグマによってオプトイン、オプトアウトが可能であり、深刻度はユーザーが選択できる。さらに、ライブラリごとのオプション(”JSON.NETのアノテーションを、そのフォールアウトを扱う準備ができるまで無視する”)が、属性によってコード内で表現可能となるかもしれない。

この設計は、以下3つの目標を達成しようとすることにもとづいて予測される。

  • ユーザーは、希望に従ってnullabilityチェックを徐々に採用できる。
  • ライブラリの作者は、利用者の環境を破壊する恐れなくnullabilityアノテーションを追加できる。
  • 上記に加え、"設定の悪夢"の感覚がない。

同一のメソッドでNull許容とNull非許容のオーバーロードをもつことはできないだろう。CLRは技術的にこれをサポートしているが、CLSまたは共通言語仕様にはない。このことは、何が起こっているかをほとんどのコンパイラが理解しないということを意味する。HaloFour氏は次のように説明する。

modreqはCLSではない。modoptはオーバーロードを許可するが、modifierは少なくとも呼び出しシグネチャにコピーされる必要があるため、用いる全てのコンパイラのほうでは特定の理解が必要となる。いずれも現存のメソッドシグネチャとの互換性を破壊する。BCL全体をまたがって非常に高速に増殖するようなものにとって、modoptの使用は大変な困難をもたらす。

ジェネリクス

さらなる警告はジェネリクスを使用する際に現れる。

  • C<T>からC<T?>にキャストするとき、型パラメーターが共変性(out)をもたない場合
  • C<T?>からC<T>にキャストするとき、型パラメーターが反変性(in)をもたない場合
  • C<T?>を使用したとき、型パラメーターが非Null制約されている場合

“class”を使用すると、ジェネリックが非Nullであるように制約づけられる。“class?”を使用するとNullは許可される。提案は次のように続く。

型パラメーターが制約づけられていない、またはNull許容だけが制約づけられている場合、状況は少し複雑になる。このことは、一致する型の引数がNull許容とNull非許容のどちらにもなりうることを意味する。この状況で安全なことは、いずれかの制約が破られたときに警告を出すことで、型パラメーターをNull許容、Null非許容の両方として扱うことだ。

配列

配列は特別な難題をもたらす。Null非許容の配列の各スロットが値を持つことを保証することが、必ずしも可能であるとは限らないためだ。

Null非許容の参照変数の配列の全ての要素が初期化されていることを適切に追跡することはできない。しかし、新しく生成された配列について、読み込まれたり渡されたりする前にいずれの要素も割り当てられていない場合、警告を出すことは可能だ。ノイズになりすぎることなく、ありがちなケースを扱うことができるだろう。

設計上のオープンな問題

default(T) の使用は警告と考えられるべきか?あるいは、Tの代わりにT?を返すとみなされるべきか?

使用状況にもとづいてnullabilityを推測し、ローカル変数から?を取り除くことは可能か?

T! xパターンを使用して、パラメーターがnullチェックを自動生成することは可能か?

Null許容値型は、x.value.methodでなくx.methodと記述できるように修正することは可能か(これは、nullチェックによってxが非nullであることがわかった場合に適用される)?

さらなる情報

 
 

Rate this Article

Relevance
Style
 
 

この記事に星をつける

おすすめ度
スタイル

BT