C# Language
ヌル統合演算子
サーチ…
構文
- var result = possibleNullObject ?? defaultValue;
パラメーター
パラメータ | 詳細 |
---|---|
possibleNullObject | ヌル値をテストする値。 nullでない場合は、この値が返されます。 null可能な型でなければなりません。 |
defaultValue | possibleNullObject がnullの場合に返される値。 possibleNullObject と同じ型でなければなりません。 |
備考
null合体演算子自体は、2つの連続した疑問符の文字です: ??
これは、条件式の簡略表です。
possibleNullObject != null ? possibleNullObject : defaultValue
左側のオペランド(テスト対象のオブジェクト)は、null値型または参照型でなければなりません。そうしないと、コンパイルエラーが発生します。
?演算子は参照型と値型の両方で動作します。
基本的な使用法
null-coalescing operator (??)
使用すると、左側のオペランドがnull
場合にヌル可能型のデフォルト値を指定できます。
string testString = null;
Console.WriteLine("The specified string is - " + (testString ?? "not provided"));
これは論理的には次のものと等価です。
string testString = null;
if (testString == null)
{
Console.WriteLine("The specified string is - not provided");
}
else
{
Console.WriteLine("The specified string is - " + testString);
}
string testString = null;
Console.WriteLine("The specified string is - " + (testString == null ? "not provided" : testString));
ヌルフォールスルーとチェーニング
左側のオペランドはNULL可能でなければならず、右側のオペランドはNULLでなければならない。それに応じて結果がタイプされます。
null不可
int? a = null;
int b = 3;
var output = a ?? b;
var type = output.GetType();
Console.WriteLine($"Output Type :{type}");
Console.WriteLine($"Output value :{output}");
出力:
型:System.Int32
値:3
Nullable
int? a = null;
int? b = null;
var output = a ?? b;
output
はint?
型になりますint?
b
と等しいか、またはnull
です。
複数の結合
合体は鎖で行うこともできます:
int? a = null;
int? b = null;
int c = 3;
var output = a ?? b ?? c;
var type = output.GetType();
Console.WriteLine($"Type :{type}");
Console.WriteLine($"value :{output}");
出力:
型:System.Int32
値:3
Null条件付きチェイン
ヌル統合オペレータは、 ヌル伝播演算子と並行して使用して、オブジェクトのプロパティへのより安全なアクセスを提供できます。
object o = null;
var output = o?.ToString() ?? "Default Value";
出力:
型:System.String
値:デフォルト値
メソッド呼び出しによるヌルの結合
null合体演算子は、 null
を返すメソッドがデフォルト値に戻ることを確実にするのを容易にします。
ヌル合体演算子を使用しない場合:
string name = GetName();
if (name == null)
name = "Unknown!";
ヌル集合演算子の場合:
string name = GetName() ?? "Unknown!";
既存のものを使用するか新規作成する
この機能が本当に役立つ一般的な使用シナリオは、コレクション内のオブジェクトを探していて、存在しない場合は新しいオブジェクトを作成する必要がある場合です。
IEnumerable<MyClass> myList = GetMyList();
var item = myList.SingleOrDefault(x => x.Id == 2) ?? new MyClass { Id = 2 };
ヌル集合演算子を使用した遅延プロパティの初期化
private List<FooBar> _fooBars;
public List<FooBar> FooBars
{
get { return _fooBars ?? (_fooBars = new List<FooBar>()); }
}
最初にプロパティ.FooBars
にアクセスすると、 _fooBars
変数はnull
として評価され、代入ステートメントに渡って結果の値を代入して評価します。
スレッドの安全性
これは、遅延安全なプロパティを実装するスレッドセーフな方法ではありません 。スレッドセーフな怠惰には、.NET Frameworkに組み込まれたLazy<T>
クラスを使用します。
式の本体を使ったC#6の構文的砂糖
C#6以降、この構文はプロパティの式本体を使用して簡略化できます。
private List<FooBar> _fooBars;
public List<FooBar> FooBars => _fooBars ?? ( _fooBars = new List<FooBar>() );
その後のプロパティへのアクセスは、 _fooBars
変数に格納された値を生成します。
MVVMパターンの例
これは、MVVMパターンでコマンドを実装するときによく使用されます。ビューモデルの構築に熱心にコマンドを初期化するのではなく、次のようにこのパターンを使用してコマンドを遅延初期化します。
private ICommand _actionCommand = null;
public ICommand ActionCommand =>
_actionCommand ?? ( _actionCommand = new DelegateCommand( DoAction ) );