オプションパターン と組み合わせてnull不可の参照タイプをどのように使用できますか?
MyOptions
という名前のオプションモデルがあるとします。
これらのオプションを必要とするサービスはIOptions<MyOptions> options
をコンストラクタに注入しました。
オプションの構成は、次のようにIServiceCollection
で行われます。
services
.AddOptions<MyOptions>()
.Configure(options =>
{
options.Name = "ABC";
});
現在、問題はMyOptions
の定義にあります:
public sealed class MyOptions
{
public string Name { get; set; }
}
これは警告を生成します:
CS8618 null可能ではないプロパティ 'Name'は初期化されていません。プロパティをnull許容として宣言することを検討してください。
Name
をnullにできるようにしたくないので、従来のnullチェックをどこにでも配置する必要があります(これはnullできない参照タイプの目的に反します)MyOptions
メソッドがオプションインスタンスを作成するため、name
クラスをnull不可のConfigure
値で作成するように強制するコンストラクターを作成することはできませんpublic string name { get; set; } = null!;
)この場合、Name
プロパティが設定されていることを確認できず、null
プロパティにName
が含まれる可能性があります。サービス)検討し忘れた他のオプションはありますか?
プロパティの予想される動作が、最初はnullを含む可能性があるがnullに設定してはならない場合は、 DisallowNullAttribute を使用してみてください。
#nullable enable
using System.Diagnostics.CodeAnalysis;
public sealed class MyOptions
{
[DisallowNull]
public string? Name { get; set; }
public static void Test()
{
var options = new MyOptions();
options.Name = null; // warning
options.Name = "Hello"; // ok
}
public static void Test2()
{
var options = new MyOptions();
options.Name.Substring(1); // warning on dereference
}
}
ここには2つの選択肢があるようです。最初の方法は、Options
のチェックを回避するために、空の文字列を使用してnull
プロパティを初期化することです(null
値の代わりに)。
public sealed class MyOptions
{
public string Name { get; set; } = "";
}
2つ目は、すべてのプロパティをnull可能なプロパティにし、 DisallowNull
前提条件と NotNull
事後条件を使用してそれらを装飾することです。
DisallowNull
は、null許容の入力引数がnullであってはならないことを意味します。NotNull
-null許容の戻り値がnullになることはありません。ただし、これらの属性は、注釈が付けられたメンバーの呼び出し元のnull許容分析にのみ影響します。したがって、null可能宣言にもかかわらず、プロパティがnull
を返すことも、null
に設定することもできないことを示しています。
public sealed class MyOptions
{
[NotNull, DisallowNull]public string? Name { get; set; }
}
と使用例
var options = new MyOptions();
options.Name = null; //warning CS8625: Cannot convert null literal to non-nullable reference type.
options.Name = "test";
ただし、次の例では警告は表示されません。オブジェクト初期化子ではnull許容分析がまだ適切に機能していないため、これを参照してください GitHubの問題
var options = new MyOptions { Name = null }; //no warning
プロパティゲッターの場合と同じように、次のサンプルでは、null許容の戻り値の型はnull
にできないことを示しているため、警告は表示されません。
var options = new MyOptions();
string test = options.Name.ToLower();
しかし、null
値を設定して取得しようとすると、警告が生成されます(コンパイラーはそのようなシナリオを検出するのに十分スマートです)
var options = new MyOptions() { Name = null };
string test = options.Name.ToLower(); //warning CS8602: Dereference of a possibly null reference.