Über diese Codezeile gelaufen:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Was bedeuten die beiden Fragezeichen? Ist es eine Art ternärer Operator?.
Es ist der Null-Koaleszenzoperator und ziemlich wie der ternäre Operator (Sofort-Wenn). Siehe auch ?? Betreiber - MSDN .
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
erweitert zu:
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
was sich weiter ausdehnt auf:
if(formsAuth != null)
FormsAuth = formsAuth;
else
FormsAuth = new FormsAuthenticationWrapper();
Auf Englisch bedeutet dies: "Wenn das, was sich links befindet, nicht null ist, verwenden Sie das, ansonsten verwenden Sie das, was rechts ist."
Beachten Sie, dass Sie beliebig viele davon nacheinander verwenden können. Die folgende Anweisung weist Answer
den ersten Nicht-Null-Code Answer#
zu (wenn alle Antworten Null sind, ist Answer
Null):
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
Erwähnenswert ist auch, dass die obige Erweiterung konzeptionell gleichwertig ist. Das Ergebnis jedes Ausdrucks wird nur einmal ausgewertet. Dies ist wichtig, wenn zum Beispiel ein Ausdruck ein Methodenaufruf mit Nebenwirkungen ist. (Dank an @Joey für den Hinweis.)
Nur weil bisher noch niemand die Zauberworte gesagt hat: Es handelt sich um den null-Koaleszenzoperator. Sie ist in Abschnitt 7.12 der Sprachspezifikation C # 3.0 definiert.
Dies ist sehr praktisch, vor allem wegen der Funktionsweise, wenn es in einem Ausdruck mehrmals verwendet wird. Ein Ausdruck der Form:
a ?? b ?? c ?? d
gibt das Ergebnis des Ausdrucks a
aus, wenn es nicht null ist, andernfalls versuchen Sie b
, andernfalls versuchen Sie c
, andernfalls versuchen Sie d
. Es schließt an jedem Punkt kurz.
Wenn der Typ von d
nicht nullfähig ist, kann auch der Typ des gesamten Ausdrucks nicht nullbar sein.
Es ist der nullkoaleszierende Operator.
http://msdn.Microsoft.com/de-de/library/ms173224.aspx
Ja, fast unmöglich zu suchen, wenn Sie nicht wissen, wie es heißt! :-)
EDIT: Und das ist eine coole Funktion aus einer anderen Frage. Sie können sie ketten.
Vielen Dank an alle, hier ist die knappste Erklärung, die ich auf der MSDN-Site gefunden habe:
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
??
gibt einen Wert für einen nullfähigen Typ an, wenn der Wert null ist. Wenn formsAuth den Wert null hat, gibt es neue FormsAuthenticationWrapper () zurück.
Die beiden Fragezeichen (??) zeigen an, dass es sich um einen Coalescing-Operator handelt.
Der Koaleszenzoperator gibt den ersten NON-NULL-Wert aus einer Kette zurück. Sie können dieses Youtube-Video sehen, das das Ganze praktisch demonstriert.
Aber lassen Sie mich noch etwas hinzufügen, was das Video sagt.
Wenn Sie die englische Bedeutung von Verschmelzung sehen, heißt es "zusammen konsolidieren". Im Folgenden finden Sie einen einfachen Koaleszenzcode, der vier Strings verkettet.
Wenn str1
null
ist, wird es str2
versuchen. Wenn str2
null
ist, wird str3
und so weiter versucht, bis eine Zeichenfolge mit einem anderen Wert als null gefunden wird.
string final = str1 ?? str2 ?? str3 ?? str4;
In einfachen Worten gibt der Coalescing-Operator den ersten NON-NULL-Wert aus einer Kette zurück.
Wenn Sie mit Ruby vertraut sind, scheint mir ||=
mit ??
von C # vergleichbar zu sein. Hier ist etwas Ruby:
irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"
Und in C #:
string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";
Nichts Gefährliches. In der Tat ist es schön. Sie können einen Standardwert hinzufügen, wenn dies wünschenswert ist, zum Beispiel:
CODE
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
Es ist eine kurze Hand für den ternären Operator.
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
Oder für diejenigen, die nicht ternär:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
koaleszierender Operator
es ist äquivalent zu
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
Nur zu Ihrem Vergnügen (wissend, dass Sie alle C # - Jungs sind ;-).
Ich denke, es hat seinen Ursprung in Smalltalk, wo es seit vielen Jahren existiert. Es wird dort definiert als:
in Objekt:
? anArgument
^ self
in UndefinedObject (aka nil's Klasse):
? anArgument
^ anArgument
Es gibt sowohl auswertende (?) Als auch nicht auswertende Versionen (??) davon.
Es wird häufig in Getter-Methoden für Lazy-Initialized-Variablen (Instanzvariablen) gefunden, die erst dann wirklich auf Null gesetzt werden.
Einige der Beispiele, wie man Werte durch Koaleszenz erhält, sind ineffizient.
Was Sie wirklich wollen, ist:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
oder
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
Dies verhindert, dass das Objekt jedes Mal neu erstellt wird. Anstatt, dass die private Variable null bleibt und bei jeder Anforderung ein neues Objekt erstellt wird, ist die private Variable zugewiesen, wenn das neue Objekt erstellt wird.
Wie in zahlreichen Antworten richtig angegeben, ist dies der "Null-Koaleszenzoperator" (??), von dem Sie vielleicht auch seinen Cousin "Null-bedingten Operator" (?.) oder ? [) Dies ist ein Operator, der häufig in Verbindung mit ?? verwendet wird.
Wird zum Testen auf Null verwendet, bevor ein Memberzugriff (?.) Oder ein Index (? [) Ausgeführt wird. Mit diesen Operatoren können Sie weniger Code schreiben, um Nullprüfungen auszuführen, insbesondere beim Absteigen in Datenstrukturen.
Zum Beispiel:
// if 'customers' or 'Order' property or 'Price' property is null,
// dollarAmount will be 0
// otherwise dollarAmount will be equal to 'customers.Order.Price'
int dollarAmount = customers?.Order?.Price ?? 0;
der alte Weg ohne ?. und ?? dies zu tun ist
int dollarAmount = customers != null
&& customers.Order!=null
&& customers.Order.Price!=null
? customers.Order.Price : 0;
das ist wortreich und umständlich.
Ich habe den ganzen Thread und viele andere gelesen, aber ich kann keine so gründliche Antwort finden wie dies ist.
Womit ich vollständig verstanden habe "Warum verwenden und wann verwenden und wie verwenden?"
Windows Communication Foundation entfesselt Von Craig McMurtry ISBN 0-672-32948-4
Es gibt zwei häufige Umstände, in denen gefragt werden soll, ob einer Instanz eines Wertetyps ein Wert zugewiesen wurde. Der erste ist, wenn die Instanz einen Wert in einer Datenbank darstellt. In einem solchen Fall möchte man die Instanz prüfen können, um festzustellen, ob tatsächlich ein Wert in der Datenbank vorhanden ist. Der andere Umstand, der für den Gegenstand dieses Buches relevanter ist, ist der, wenn die Instanz ein Datenelement darstellt, das von einer entfernten Quelle empfangen wurde. Wieder möchte man aus der Instanz herausfinden, ob ein Wert für dieses Datenelement empfangen wurde.
Das .NET Framework 2.0 enthält eine generische Typdefinition, die Fälle wie diese vorsieht, in denen einer Instanz eines Wertetyps null zugewiesen werden soll und getestet werden soll, ob der Wert der Instanz null ist. Diese generische Typdefinition ist System.Nullable, die die generischen Typargumente, die für T möglicherweise ersetzt werden können, auf Wertetypen einschränken . Instanzen von Typen, die aus System.Nullable erstellt wurden, können den Wert null erhalten. In der Tat sind ihre Werte standardmäßig null. Daher können Typen, die aus System.Nullable erstellt werden, als auswertbare Werttypen bezeichnet werden. System.Nullable hat die Eigenschaft Value, mit der der einer Instanz von Zugewiesenen Wert einen daraus konstruierten Typ erreichen kann erhalten, wenn der Wert der Instanz nicht null ist ..__ Daher kann man schreiben:
System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}
Die Programmiersprache C # bietet eine abgekürzte Syntax für die Deklaration von Typen , Die aus System.Nullable erstellt wurden. Diese Syntax erlaubt eine Abkürzung:
System.Nullable<int> myNullableInteger;
zu
int? myNullableInteger;
Der Compiler verhindert, dass einer versucht, den Wert eines nullwertfähigen Wertetyps einem normalen Wertetyp auf folgende Weise zuzuweisen:
int? myNullableInteger = null;
int myInteger = myNullableInteger;
Dies verhindert, dass der Werttyp nullable den Wert null haben kann, den er in diesem Fall tatsächlich hätte, und dieser Wert kann keinem normalen Werttyp zugewiesen werden. Obwohl der Compiler diesen Code zulassen würde,
int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;
Die zweite Anweisung würde eine Ausnahme auslösen, da jeder Versuch, auf die System.Nullable.Value-Eigenschaft zuzugreifen, eine ungültige Operation ist, wenn dem aus System.Nullable erstellten Typ Kein gültiger Wert von T zugewiesen wurde. was in diesem Fall nicht passiert ist.
Eine geeignete Methode zum Zuweisen des Werts eines nullwertfähigen Wertetyps zu einem gewöhnlichen Wertetyp ist die Verwendung der System.Nullable.HasValue-Eigenschaft, um festzustellen, ob dem nullwertfähigen Werttyp ein gültiger Wert von T zugewiesen wurde:
int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}
Eine andere Option ist die Verwendung dieser Syntax:
int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;
Durch welche der gewöhnlichen Ganzzahl myInteger der Wert der nullfähigen Ganzzahl "myNullableInteger" zugewiesen wird, wenn dieser eine gültige Ganzzahl zugewiesen wurde; Andernfalls wird myInteger der Wert -1 zugewiesen.
Der ??
-Operator wird als nullkoaleszierender Operator bezeichnet. Es gibt den linken Operanden zurück, wenn der Operand nicht Null ist. Andernfalls wird der rechte Operand zurückgegeben.
int? variable1 = null;
int variable2 = variable1 ?? 100;
Setzen Sie variable2
auf den Wert von variable1
, wenn variable1
NICHT NULL ist; Andernfalls, wenn variable1 == null
, setzen Sie variable2
auf 100.
Es ist ein nullkoaleszierender Operator, der ähnlich arbeitet wie ein ternärer Operator.
a ?? b => a !=null ? a : b
Ein weiterer interessanter Punkt dafür ist "Ein nullfähiger Typ kann einen Wert enthalten oder kann undefiniert sein" . Wenn Sie also versuchen, einem nicht nullfähigen Werttyp einen nullfähigen Werttyp zuzuweisen Sie erhalten einen Fehler bei der Kompilierung.
int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.
Also, um das zu tun? Operator:
z = x ?? 1; // with ?? operator there are no issues
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
ist äquivalent zu
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
Aber das Coole daran ist, dass man sie ketten kann, wie andere Leute sagten .. Das einzige, was nicht angesprochen wird, ist, dass man es tatsächlich benutzen kann, um eine Ausnahme zu werfen.
A = A ?? B ?? throw new Exception("A and B are both NULL");