Antworten:
Es ist der nullbedingte Operator. Es bedeutet im Grunde:
"Bewerten Sie den ersten Operanden. Wenn dies null ist, stoppen Sie mit dem Ergebnis null. Andernfalls bewerten Sie den zweiten Operanden (als Elementzugriff des ersten Operanden)."
In Ihrem Beispiel, dass der Punkt ist , wenn a
ist null
, dann a?.PropertyOfA
zu bewerten , wird null
eher als eine Ausnahme zu werfen - es wird dann das Vergleichen null
Verweis mit foo
(string die mit ==
Überlast), finden sie nicht gleich sind und die Ausführung wird der Körper der gehen in if
Aussage .
Mit anderen Worten, es ist so:
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
... außer dass a
nur einmal ausgewertet wird.
Beachten Sie, dass dies auch den Typ des Ausdrucks ändern kann. Betrachten Sie zum Beispiel FileInfo.Length
. Das ist eine Eigenschaft vom Typ long
, aber wenn Sie sie mit dem bedingten Nulloperator verwenden, erhalten Sie einen Ausdruck vom Typ long?
:
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
Dies kann sehr nützlich sein, wenn Sie eine Hierarchie reduzieren und / oder Objekte zuordnen. Anstatt:
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;
}
Es kann wie folgt geschrieben werden (gleiche Logik wie oben)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
DotNetFiddle.Net Arbeitsbeispiel .
(die ?? oder Null-Koaleszenz Operator ist anders als die ? oder null Bedingungsoperator ).
Es kann auch außerhalb von Zuweisungsoperatoren mit Aktion verwendet werden. Anstatt
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
Es kann vereinfacht werden zu:
myAction?.Invoke(TValue);
using System;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
Ergebnis:
Test 2
|| Model.Model2.Model3.Model4.Name == null
die gleiche Logik zu haben, sonst Fall Model.Model2.Model3.Model4.Name
ist null
, mapped.Name
wird bleibennull
Model.Model2.Model3.Model4.Name
ist null
.
else
-zweig springen und haben mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
, während Ihr zweites Beispiel ersetzen würde mapped.Name = "N/A"
. Siehe die bearbeitete DotNetFiddle
Dies ist für C # relativ neu, was es uns leicht macht, die Funktionen in Bezug auf die Null- oder Nicht-Null- Werte in der Methodenverkettung aufzurufen.
Der alte Weg, dasselbe zu erreichen, war:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
und jetzt ist es viel einfacher geworden mit nur:
member?.someFunction(var someParam);
Ich empfehle Ihnen dringend, es hier zu lesen: