回答:
これはnull条件演算子です。それは基本的には以下を意味します:
「最初のオペランドを評価します。それがnullの場合は、結果をnullにして停止します。それ以外の場合は、2番目のオペランドを(最初のオペランドのメンバーアクセスとして)評価します。」
あなたの例では、ポイントがあればということでa
ありnull
、その後a?.PropertyOfA
に評価しますnull
例外を投げるのではなく-それは、その比較しますnull
と、参照foo
(文字列の使用して==
過負荷)を、彼らは同じじゃない見つけ、実行はの体内に入りますif
声明。
つまり、次のようになります。
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
...それ以外a
は一度だけ評価されます。
これにより、式のタイプも変わることに注意してください。たとえば、を検討してくださいFileInfo.Length
。これはtypeのプロパティですlong
が、null条件演算子と共に使用すると、typeの式になりlong?
ます。
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
階層をフラット化したり、オブジェクトをマッピングしたりするときに非常に役立ちます。の代わりに:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
次のように書くことができます(上記と同じロジック)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
(??またはnullの合体演算子は、?またはnullの条件演算子とは異なります)。
また、Actionの代入演算子以外でも使用できます。の代わりに
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
次のように簡略化できます。
myAction?.Invoke(TValue);
システムの使用;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
結果:
テスト2
|| Model.Model2.Model3.Model4.Name == null
同じロジックを持つために追加する必要があると思います 、そうでない場合Model.Model2.Model3.Model4.Name
はnull
、mapped.Name
残りますnull
Model.Model2.Model3.Model4.Name
ですnull
。
else
-branchにジャンプして持ってmapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
いますが、2番目の例はに置き換えられmapped.Name = "N/A"
ます。編集されたDotNetFiddleを
これはC#で比較的新しく、メソッドチェーンでnullまたはnull以外の値に関して関数を簡単に呼び出すことができます。
同じことを達成する古い方法は:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
そして今、それは次のようにしてはるかに簡単になりました:
member?.someFunction(var someParam);
こちらをお読みになることを強くお勧めします。