1994 Stimmen

Was bedeuten zwei Fragezeichen zusammen in C#?

Bin auf diese Codezeile gestoßen:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

Was bedeuten die beiden Fragezeichen, handelt es sich um eine Art ternären Operator? Es ist schwer, in Google nachzuschlagen.

70 Stimmen

Es ist definitiv no ein ternärer Operator - er hat nur zwei Operanden! Er ist ein bisschen wie der bedingte Operator (der ist ternär), aber der Null-Koaleszenz-Operator ist ein binärer Operator.

104 Stimmen

Ich habe es in einem Vorstellungsgespräch erklärt, in dem der potenzielle Arbeitgeber zuvor Zweifel an meinen C#-Fähigkeiten geäußert hatte, da ich zuvor eine Zeit lang beruflich mit Java gearbeitet hatte. Sie hatten vorher noch nie etwas davon gehört und stellten meine Vertrautheit mit C# danach nicht mehr in Frage :)

85 Stimmen

@Jon Skeet Seit dem Kerl, der die Beatles ablehnte, gab es keine derartigen Misserfolge bei der Anerkennung von Fähigkeiten mehr :-) Schicken Sie ihnen von nun an einfach ein Exemplar Ihres Buches mit einem Link zu Ihrem SO-Profil auf der Innenseite des Umschlags.

11voto

dqninh Punkte 111

Daran ist nichts Gefährliches. Es ist sogar sehr schön. Sie können zum Beispiel einen Standardwert hinzufügen, wenn dies erwünscht ist:

CODE

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;

1 Stimmen

So könnten beispielsweise x1, x2, x3 und x4 nullbare Typen sein: int? x1 = null; Ist das richtig?

1 Stimmen

@KevinMeredith x1 - x4 MÜSSEN nullbare Typen sein: Es macht keinen Sinn zu sagen, "das Ergebnis ist 0 wenn x4 ist ein Wert, den er unmöglich annehmen kann" ( null ). "Nullable type" umfasst hier sowohl nullable Wert Typen und Referenztypen, versteht sich. Es ist ein Kompilierfehler, wenn eine oder mehrere der verketteten Variablen (außer der letzten) nicht nullbar sind.

11voto

Anmerkung:

Ich habe diesen und viele andere Threads durchgelesen, aber ich kann keine so gründliche Antwort finden wie diese.

Damit habe ich das "Warum?" und "Wann?" und "Wie?" vollständig verstanden.

Quelle:

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

Nullbare Wertetypen

Es gibt zwei häufige Situationen, in denen man wissen möchte, ob ein Wert einer Instanz einer Wertart zugewiesen wurde. Der erste Fall ist, dass die Instanz einen Wert in einer Datenbank darstellt. In einem solchen Fall möchte man in der Lage sein, die Instanz zu untersuchen, um festzustellen, ob ein Wert tatsächlich in der Datenbank vorhanden ist. Der andere Fall, der für das Thema dieses Buches von größerer Bedeutung ist, liegt vor, wenn die Instanz ein Datenelement darstellt, das von einer entfernten Quelle empfangen wurde. Auch hier möchte man anhand der Instanz feststellen, ob ein Wert für dieses Datenelement empfangen wurde.

Das .NET Framework 2.0 enthält eine generische Typdefinition, die für Fälle wie diese sorgt, in denen man einer Instanz eines Werttyps null zuweisen und prüfen möchte, ob der Wert der Instanz null ist. Diese generische Typdefinition lautet System.Nullable<T> die die generischen Typargumente, die anstelle von T verwendet werden können, auf Werttypen einschränkt. Instanzen von Typen, die aus System.Nullable<T> kann der Wert Null zugewiesen werden; tatsächlich sind ihre Werte standardmäßig Null. Daher sind Typen, die aus System.Nullable<T> können als nullbare Werttypen bezeichnet werden. System.Nullable<T> hat eine Eigenschaft, Value, mit der der Wert, der einer Instanz von zugewiesenen Wert erhalten werden kann, 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<T> . Mit dieser Syntax kann man abkürzen:

System.Nullable<int> myNullableInteger;

zu

int? myNullableInteger;

Der Compiler verhindert, dass man versucht, den Wert eines nullbaren Werttyps auf diese Weise einem gewöhnlichen Werttyp zuzuweisen:

int? myNullableInteger = null;
int myInteger = myNullableInteger;

Er verhindert dies, weil der Werttyp nullable den Wert null haben könnte, den er in diesem Fall tatsächlich hat, und dieser Wert kann keinem gewöhnlichen 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 Zugriff auf die System.Nullable<T> .Value-Eigenschaft ist eine ungültige Operation, wenn der Typ konstruiert aus System.Nullable<T> kein gültiger Wert von T zugewiesen wurde, was in diesem Fall nicht der Fall war.

Schlussfolgerung:

Ein geeigneter Weg, um den Wert eines nullbaren Werttyps einem gewöhnlichen Werttyp zuzuweisen, ist die Verwendung der System.Nullable<T> .HasValue-Eigenschaft, um festzustellen, ob der nicht löschbaren Wertart ein gültiger Wert von T zugewiesen wurde:

int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}

Eine andere Möglichkeit ist die Verwendung dieser Syntax:

int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;

Dabei wird der gewöhnlichen Ganzzahl myInteger der Wert der löschbaren Ganzzahl "myNullableInteger" zugewiesen, wenn letzterer ein gültiger Ganzzahlwert zugewiesen wurde; andernfalls wird myInteger der Wert -1 zugewiesen.

11voto

aku Punkte 118808

Koaleszenz-Operator

es entspricht

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

9voto

KingOfHypocrites Punkte 9047

Einige der hier genannten Beispiele für die Ermittlung von Werten durch Koaleszenz sind ineffizient.

Was Sie wirklich wollen, ist:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

o

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

Dadurch wird verhindert, dass das Objekt jedes Mal neu erstellt werden muss. Anstatt dass die private Variable null bleibt und bei jeder Anfrage ein neues Objekt erstellt wird, wird so sichergestellt, dass die private Variable zugewiesen wird, wenn das neue Objekt erstellt wird.

0 Stimmen

Ist nicht ?? Abkürzung bewertet? new FormsAuthenticationWrapper(); wird ausgewertet wenn und nur wenn _formsAuthWrapper ist gleich Null.

0 Stimmen

Ja, genau das ist der springende Punkt. Sie wollen die Methode nur aufrufen, wenn die Variable null ist. @MSalters

9voto

blabla999 Punkte 3082

Nur zu Ihrer Belustigung (da Sie ja alle C#-Leute sind ;-).

Ich glaube, es hat seinen Ursprung in Smalltalk, wo es seit vielen Jahren verwendet wird. Es ist dort definiert als:

in Objekt:

? anArgument
    ^ self

in UndefinedObject (auch bekannt als die Klasse von nil):

? anArgument
    ^ anArgument

Es gibt sowohl wertende (?) als auch nicht wertende Versionen (??) davon.
Sie findet sich häufig in Getter-Methoden für private (Instanz-)Variablen, die nicht initialisiert werden, bis sie wirklich benötigt werden.

0 Stimmen

Klingt wie Wrapping ViewState mit einer Eigenschaft auf ein UserControl. Initialisieren Sie nur beim ersten Get, wenn es nicht vorher gesetzt wurde =)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X