wake-up-neo.com

Was bedeuten zwei Fragezeichen in C #?

Über diese Codezeile gelaufen:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

Was bedeuten die beiden Fragezeichen? Ist es eine Art ternärer Operator?.

1412
Edward Tanguay

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.)

1900
lc.

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.

254
Jon Skeet

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.

Versteckte Funktionen von C #?

67
Iain Holder

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;
24
Edward Tanguay

?? 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. 

20
RedFilter

enter image description here

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 str1null ist, wird es str2 versuchen. Wenn str2null 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. 

18

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";
12
Sarah Vessels

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;
11
dqninh

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();
}
11
Benjamin Autin

koaleszierender Operator

es ist äquivalent zu

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
10
aku

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.

10
blabla999

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.

9

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.

Nullbedingter Operator

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.

9
brakeroo

Hinweis:

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

Quelle:

Windows Communication Foundation entfesselt Von Craig McMurtry ISBN 0-672-32948-4

Nullwerttypen

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.

Fazit:

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.

7
Wiqi

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.

0
Md.Jubayer

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
0
Ashish Mishra
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");
0
NolePTR