C# 8の一部が.NET Frameworkでサポートされることはないが、Null許容参照型のトリックを知っていればオンにできる。
C# 8を有効にする
まず、Visual Studio 2019 バージョン16.3以降を利用していることを確認する。
次に、C# 8用プロジェクトを構成する。Visual Studioで作業に慣れている場合、プロジェクトの設定で簡単にできると考えるだろう。残念ながら、もうそれはできない。
新しいルールでは、C#のデフォルトバージョンは、対象とするフレームワークで決定される。.NET Core 3.0と.NET Standard 2.1だけがC# 8であり、その他はすべてC# 7.3として開始される。
プロジェクトファイルを編集して、これを上書きできる。プロジェクトの.csprojファイルを開いて、PropertyGroupにこの行を追加する。
<LangVersion>8.0</LangVersion>
モダンプロジェクト形式を使っている場合は、ソリューションエクスプローラーでプロジェクトをダブルクリックするだけで開くことができる。XMLファイルのルートは次のようになるため、このフォーマットを認識できる:
<Project Sdk="Microsoft.NET.Sdk">
レガシープロジェクト形式を使っている場合、直接編集するのは少し複雑だ。Visual Studioを閉じて、メモ帳などのテキストエディターを使うのが1つの選択肢である。または「Edit Project File」コマンドを追加するPower Commands for Visual Studioをインストールできる。例えば、XMLファイルのルートは以下のようになる:
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Null許容参照型を有効にする:
次のステップはNull許容参照型を有効にすることである。モダンプロジェクト形式を使っている場合、言語バージョンの後に次の行を追加するだけで、グローバルにできる。
<Nullable>enable</Nullable>
レガシープロジェクト形式を使っている場合、これは機能しない。エラーは発生せず、コンパイラは設定を無視するだけである。そのため、ファイルごとに有効にする必要がある。これをするには、各ファイルの先頭にnullableディレクティブを追加する必要がある。
#nullable enable
機能を徐々に有効にしたい場合は、モダンプロジェクトでもこれは機能する。
Nullability属性
nullチェッカーの動作を微調整するために使われる様々な属性がある。以下の関数を見てほしい:
bool TryGet(int key, out Customer? customer)
暗示コントラクトとしてcustomerパラメーターがnullでなければtrueが返る。逆にcustomerがnullの時にはfalseが返る。
だがこれはシグニチャの一部ではないため、関数をそのまま使う場合は、常にcustomerのnullチェックが必要になる。回避するためには、動作を明確にする属性を追加する必要がある:
bool TryGet(int key, [NotNullWhen(true)] out Customer? customer)
コンパイラの観点から見ると、trueが返される場合customerがnullになることはないということである。falseが返されたときについてはなにも言ってないが、シグニチャの問題を解決するには十分である。
Null許容参照型を試す(Try out Nullable Reference Types)というタイトルのPhillip Carter氏の記事で、様々な属性について詳しく説明している。
- 条件付き事後条件: MaybeNotNullWhen(bool), NotNullWhen(bool)
- 依存null-ness: NotNullIfNotNull
- フロー: DoesNotReturn, DoesNotReturnIf(bool)
- 事後条件: MaybeNull, NotNull
- 前提条件: AllowNull, DisallowNull
古いプロジェクトのNullability属性
これらの属性を実際に使用するには、それらが定義されている必要がある。.NET Standard 2.1か.NET Core 3.0を使っている場合、すでにそれが完了している。それ以外の場合は、プロジェクトの一部としてそれらを作る必要がある。
これに対処する従来の方法は、新しい.NET Core 3プロジェクトを作って、F12を使用して目的の属性をリバースエンジニアリングすることである。次にそれをプロジェクトにペーストして不足している詳細を追加することで、属性には数分しかかからない。
より簡単な方法は、Manuel Römer氏によるNullable packageをインストールすることである。これによりプロジェクトに必要な属性情報が全て含まれているNullableAttributes.csファイルをコピーする。このパッケージはコンパイルされたコンポーネントではなく、ただの1ソースコードファイルである。
いずれにしても、全ての属性は「internal」としてマークされており、パブリックではない。これはバックポートされた属性と他のライブラリとの衝突を避けるためである。
参考文献
著者について
Jonathan Allenは90年代後半にヘルスクリニックのMISプロジェクトに参加し、AccessとExcelから次第にエンタープライズ・ソリューションに移っていった。金融セクター向けの自動取引システムに5年間費やしたあと、ロボット倉庫のUI、がん研究ソフトウェアの中間層、大手不動産保険会社のビックデータニーズなど、様々なプロジェクトのコンサルタントになった。余暇には16世紀の武術について学び、書くことを楽しんでいる。