BT

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

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース C# 8 Null許容参照型のアップデート

C# 8 Null許容参照型のアップデート

原文(投稿日:2019/06/26)へのリンク

C# 8のNull許容参照型(nullable refence types)の作業は継続されており、最終リリース前に対処する必要があるエッジケースと、開発者が書く必要がある定型コードを削減する新しい機会を明らかにしている。

以下はNull許容型に対するオープンクエスチョンである:

  • MaybeNullNotNullのどちらが優先されるか?
  • AllowNullNotNullのどちらが値型に許可されるべきか?
  • !は警告なしで最上位レベルのNull許可を変更するべきか?
  • ref引数は、常に代入されると仮定するべきか?
  • メンバーのNull許可状態を維持して変換するべきか?
  • var?をサポートするべきか、その場合の未解決問題はなにか?
  • この方針に従ってvar? (x, y) = ...の分解を可能にするか?
  • typeof(string?)は、nullableアノテーションを尊重できないが、許可する(もしくは禁止する)べきか?
  • フロー分析でnullableアノテーションを計算するとき、コンテキストを使用する必要があるか?
  • 動的呼び出しの結果は、一般的に静的分析のスコープ外のため、non-nullとして扱うべきか?

その他の質問にも答えた。これはコードの書き方に影響を与えるいくつかのハイライトである。

  • 条件付き呼び出しのNull許容性(x?.F())は常にNull許容である。
  • Throwステートメントとthrow式は、オペランドがnullになる可能性があるときに警告する。
  • 到達不能なコードにNull許容性警告は表示しない。
  • 匿名型のNull許容性は推論されたシグニチャの一部である。

宣言的引数のNullチェック

Null許容参照型の問題の1つは、コンパイラに対する単なる提案である。パラメータをnon-nullableとしてマークしたとしても、特にリフレクションやdynamicを使っている場合には、誰かが誤ってnullを渡すことを止めることができない。つまり関数の先頭にnull引数チェックをなくすことはできないということである。

引数のnull検証の単純化において、コンパイラにnullチェックを生成するように伝えることができる。2つの構文が提案されている。

void Insert(string s!)
void Insert(string! s)

感嘆符オペレーター(!)は、型名とパラメータ名のどちらかに使われる。1つ目のバージョンの引数は、関数の実装詳細であり、メソッドシグニチャの一部ではない。2つ目の引数は、より一貫したNull許可バージョン(void Insert(string? s))で、メソッドシグニチャであるべきである。シグニチャの一部であることはとても重要で、インターフェイスメソッドにも適用できる。そして継承とメソッドのオーバーライドに対しても疑問を投げかける。

別の疑問は、それがどのように実装されるのかである。オプションは次の通り:

  1. C#はILのインラインチェックを発行する
  2. C#はILのヘルパーメソッド呼び出しを発行する
  3. C#はタグを発行するだけなので、JITプロセスはチェックの実行方法を決定できる

もう1つの疑問は、型がNull許容(int?)だが、nullチェックが望まれているときになにが起きるのか。サポートされている場合、(void Insert(int?! i))のシグニチャに矛盾が生じる可能性がある。

カスタムシンタックスの代わりに属性([NotNull])を使ったものはまだ議論されていない。より冗長ではあるが、宣言的引数チェックの他の形式の前例になるだろう。

この記事に星をつける

おすすめ度
スタイル

BT