null-coalescing-operator operator - Cosa significano due punti interrogativi insieme in C#?





vb net (14)


Niente di pericoloso in questo. In effetti, è bello. È possibile aggiungere un valore predefinito se ciò è auspicabile, ad esempio:

CODICE

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

Attraversato questa riga di codice:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

Cosa significano i due punti interrogativi, è una specie di operatore ternario? È difficile cercare su Google.




Solo perché nessun altro ha ancora detto le parole magiche: è l' operatore a coalescenza nulla . È definito nella sezione 7.12 delle specifiche del linguaggio C # 3.0 .

È molto utile, soprattutto per il modo in cui funziona quando viene utilizzato più volte in un'espressione. Un'espressione della forma:

a ?? b ?? c ?? d

darà il risultato dell'espressione a se non è nullo, altrimenti prova b , altrimenti prova c , altrimenti prova d . Cortocircuito in ogni punto.

Inoltre, se il tipo di d non è annullabile, anche il tipo dell'intera espressione non è annullabile.




operatore coalescente

è equivalente a

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



Se hai familiarità con Ruby, il suo ||= sembra simile a C # ?? per me. Ecco alcuni 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"

E in C #:

string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";



?? è lì per fornire un valore per un tipo nullable quando il valore è nullo. Quindi, se formsAuth è null, restituirà new FormsAuthenticationWrapper ().




I due punti interrogativi (??) indicano che è un operatore di Coalescing.

L'operatore a coalescenza restituisce il primo valore NON-NULL da una catena. Puoi vedere questo video di youtube che dimostra praticamente tutto.

Ma lascia che aggiunga altro a ciò che dice il video.

Se vedi il significato inglese di coalescenza, dice "consolida insieme". Ad esempio qui di seguito è un semplice codice coalescente che catene quattro stringhe.

Quindi se str1 è null proverà str2 , se str2 è null proverà str3 e così via finché non troverà una stringa con un valore non nullo.

string final = str1 ?? str2 ?? str3 ?? str4;

In parole semplici, l'operatore di coalescenza restituisce il primo valore NON-NULL da una catena.




FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

è equivalente a

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

Ma la cosa bella è che puoi incatenarli, come hanno detto altre persone. L'unico sottile che non viene toccato è che puoi effettivamente usarlo per lanciare un'eccezione.

A = A ?? B ?? throw new Exception("A and B are both NULL");



È l'operatore a coalescenza nulla e molto simile all'operatore ternario (immediato-se). Vedi anche ?? Operatore - MSDN .

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

si espande a:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

che si espande ulteriormente a:

if(formsAuth != null)
    FormsAuth = formsAuth;
else
    FormsAuth = new FormsAuthenticationWrapper();

In inglese significa "Se tutto ciò che è a sinistra non è nullo, usalo, altrimenti usa ciò che è a destra".

Si noti che è possibile utilizzare qualsiasi numero di questi in sequenza. La seguente affermazione assegnerà la prima Answer# numerica non nullo alla Answer (se tutte le risposte sono nulle allora la Answer è nullo):

string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

Vale anche la pena ricordare che, mentre l'espansione sopra è concettualmente equivalente, il risultato di ciascuna espressione viene valutato una sola volta. Questo è importante se per esempio un'espressione è una chiamata al metodo con effetti collaterali. (Credito a @Joey per averlo indicato.)




È un operatore a coalescenza nulla che funziona in modo simile a un operatore ternario.

    a ?? b  => a !=null ? a : b 

Un altro punto interessante per questo è, "Un tipo nullable può contenere un valore, o può essere indefinito" . Quindi se provate ad assegnare un tipo di valore nullable a un tipo di valore non annullabile otterrete un errore in fase di compilazione.

int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.

Quindi per farlo usando ?? operatore:

z = x ?? 1; // with ?? operator there are no issues



Grazie a tutti, ecco la spiegazione più succinta che ho trovato sul sito MSDN:

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;



Alcuni esempi qui di ottenere valori usando la coalescenza sono inefficienti.

Quello che vuoi veramente è:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

o

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

Ciò impedisce che l'oggetto venga ricreato ogni volta. Invece della variabile privata che rimane nullo e di un nuovo oggetto che viene creato su ogni richiesta, questo assicura che la variabile privata sia assegnata se il nuovo oggetto viene creato.




Solo per il vostro divertimento (sapendo che siete tutti ragazzi di C # ;-).

Penso che sia nato in Smalltalk, dove è stato intorno per molti anni. È definito lì come:

in oggetto:

? anArgument
    ^ self

in UndefinedObject (aka classe di nil):

? anArgument
    ^ anArgument

Ci sono sia versioni valutative (?) Che non valutative (??) di questo.
Si trova spesso nei metodi getter per variabili private (istanze) pigro-inizializzate, che rimangono nulle fino a quando non sono realmente necessarie.




È una mano corta per l'operatore ternario.

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

O per coloro che non fanno ternario:

if (formsAuth != null)
{
  FormsAuth = formsAuth;
}
else
{
  FormsAuth = new FormsAuthenticationWrapper();
}



Questo è sicuramente un bug.

public class Program {
    static A? X() {
        Console.WriteLine("X()");
        return new A();
    }
    static B? Y() {
        Console.WriteLine("Y()");
        return new B();
    }
    static C? Z() {
        Console.WriteLine("Z()");
        return new C();
    }

    public static void Main() {
        C? test = (X() ?? Y()) ?? Z();
    }
}

Questo codice produrrà:

X()
X()
A to B (0)
X()
X()
A to B (0)
B to C (0)

Questo mi ha fatto pensare che la prima parte di ciascuno ?? l'espressione di coalescenza viene valutata due volte. Questo codice lo ha dimostrato:

B? test= (X() ?? Y());

uscite:

X()
X()
A to B (0)

Questo sembra accadere solo quando l'espressione richiede una conversione tra due tipi annullabili; Ho provato varie permutazioni con uno dei lati di una stringa, e nessuno di loro ha causato questo comportamento.







c# null-coalescing-operator