疑問符とドット演算子は何ですか?C#6.0で意味ですか?


359

VS2015プレビューのC#6.0では、次の?.ように使用できる新しい演算子があります。

public class A {
   string PropertyOfA { get; set; }
}

...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
   //somecode
}

正確には何をしますか?

回答:


500

これは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

8
null条件演算子と呼ばれていませんか?
SLaks

1
@SLaks:「条件付きnull」だと思っていましたが、間違っている可能性があります。前回、Roslyn言語機能のドキュメントを確認したところ、名前が変更されていませんでした。たぶん、ソースはここの権限です-チェックします。
Jon Skeet

3
@SLaks:もちろんです。SyntaxKindでは、明らかにConditionalAccessExpressionであり、迷惑なことにそれらのどちらでもありません...
Jon Skeet

12
「エルビス」という名前のオペレーターを好んだ:P
Ahmed ilyas

3
記録のために、私はこの演算子の5つの異なる名前を見ました。安全なナビゲーション、null条件付き、null伝播、条件付きアクセス、Elvisです。
ジジ

81

階層をフラット化したり、オブジェクトをマッピングしたりするときに非常に役立ちます。の代わりに:

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";

DotNetFiddle.Netの動作例

??またはnullの合体演算子は、?またはnullの条件演算とは異なります)。

また、Actionの代入演算子以外でも使用できます。の代わりに

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}

次のように簡略化できます。

myAction?.Invoke(TValue);

DotNetFiddleの例

システムの使用;

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


27
何を探している人を救うために?? これは、null結合演算子であり、nullでない場合はNameを返し、そうでない場合は「N / A」を返します。
Steve

6
@Erik Philips私はあなたが|| Model.Model2.Model3.Model4.Name == null 同じロジックを持つために追加する必要があると思います 、そうでない場合Model.Model2.Model3.Model4.Namenullmapped.Name残りますnull
RazvanR

2
@ErikPhilips同じページではないと思います。場合は、両方のあなたのケースでは何が起こるか見てみてくださいModel.Model2.Model3.Model4.Nameですnull
RazvanR 2017年

1
結果は「N / A」です。最初のコメントをもう一度お読みください。 DotNetFiddle.Netの動作例
エリックフィリップス

7
@ErikPhilips:これは最初の例とは関係がないため、最初のコメントとは関係ありません。この例では、else-branchにジャンプして持ってmapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = nullいますが、2番目の例はに置き換えられmapped.Name = "N/A"ます。編集されたDotNetFiddleを
derM

3

これはC#で比較的新しく、メソッドチェーンでnullまたはnull以外の値に関して関数を簡単に呼び出すことができます。

同じことを達成する古い方法は:

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

そして今、それは次のようにしてはるかに簡単になりました:

member?.someFunction(var someParam);

こちらをお読みになることを強くお勧めします。

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.