[c#] Cosa significano due punti interrogativi insieme in C #?


Answers

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.

Question

Attraversato questa riga di codice:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

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




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;



Nota:

Ho letto tutto questo thread e molti altri, ma non riesco a trovare una risposta esaustiva come questa.

Con il quale ho capito completamente il "perché usare ?? e quando usare ?? e come usare ??".

Fonte:

Fondamento di comunicazione di Windows scatenato da Craig McMurtry ISBN 0-672-32948-4

Nullable Value Types

Esistono due circostanze comuni in cui si vorrebbe sapere se un valore è stato assegnato a un'istanza di un tipo di valore. Il primo è quando l'istanza rappresenta un valore in un database. In tal caso, si vorrebbe poter esaminare l'istanza per accertare se un valore sia effettivamente presente nel database. L'altra circostanza, che è più pertinente alla materia di questo libro, è quando l'istanza rappresenta un elemento di dati ricevuto da qualche fonte remota. Ancora una volta, si vorrebbe determinare dall'istanza se è stato ricevuto un valore per quell'elemento di dati.

.NET Framework 2.0 incorpora una definizione di tipo generico che fornisce casi come questi in cui si desidera assegnare null a un'istanza di un tipo di valore e verificare se il valore dell'istanza è nullo. Quella definizione di tipo generico è System.Nullable, che limita gli argomenti di tipo generico che possono essere sostituiti a T per i tipi di valore. Alle istanze di tipi costruite da System.Nullable può essere assegnato un valore null; in effetti, i loro valori sono nulli di default. Pertanto, i tipi costruiti da System.Nullable possono essere indicati come tipi di valori nullable. System.Nullable ha una proprietà, Value, per cui il valore assegnato a un'istanza di un tipo costruito da esso può essere ottenuto se il valore dell'istanza non è nullo. Pertanto, si può scrivere:

System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}

Il linguaggio di programmazione C # fornisce una sintassi abbreviata per dichiarare i tipi costruiti da System.Nullable. Questa sintassi consente di abbreviare:

System.Nullable<int> myNullableInteger;

a

int? myNullableInteger;

Il compilatore impedirà a uno di tentare di assegnare il valore di un tipo di valore nullable a un tipo di valore ordinario in questo modo:

int? myNullableInteger = null;
int myInteger = myNullableInteger;

Impedisce a uno di farlo perché il tipo di valore nullable potrebbe avere il valore null, che in realtà avrebbe in questo caso, e quel valore non può essere assegnato ad un tipo di valore ordinario. Sebbene il compilatore consentirebbe questo codice,

int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;

La seconda istruzione causerebbe il lancio di un'eccezione perché qualsiasi tentativo di accesso alla proprietà System.Nullable.Value è un'operazione non valida se il tipo creato da System.Nullable non ha ricevuto un valore valido di T, cosa che non è avvenuta in questo Astuccio.

Conclusione:

Un modo corretto per assegnare il valore di un tipo di valore nullable a un tipo di valore ordinario consiste nell'utilizzare la proprietà System.Nullable.HasValue per verificare se un valore valido di T è stato assegnato al tipo di valore nullable:

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

Un'altra opzione è usare questa sintassi:

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

Con il quale all'intero ordinario myInteger viene assegnato il valore del numero intero nullable "myNullableInteger" se a quest'ultimo è stato assegnato un valore intero valido; in caso contrario, a myInteger viene assegnato il valore di -1.




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;



È 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



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.




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.




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



Related