2011-01-23 13 views
7

Così insteed della scrittura:Cosa c'è che non va ?? operatore usato in questo modo:

if (obj.Collection == null) 
    obj.Collection = new Collection(); 
obj.Collection.Add(something); 

ho pensato di scrivere:

obj.Collection = obj.Collection ?? new Collection; 
obj.Collection.Add(something); 

E 'sorta di sente male, soprattutto questa parte "obj.Collection = obj.Collection .. . "

Cosa ne pensate?

saluti,

+4

Perché ci si sente male? – alexn

+0

Mi sembra giusto – Vadim

+4

Qual è il problema? Hai un problema con 'x = x + 1;'? –

risposta

15

Se dovessi scegliere tra questi due blocchi di codice, userei il primo. È più leggibile ed è un modello comune. ?? è utile in scenari in cui è necessario impostare un valore predefinito (ad esempio, DateTime date = nullableDateTimeInstance ?? defaultDate;).

Ma sinceramente, proverei a non finire nella situazione in cui voglio aggiungere alla raccolta ed è possibile che la raccolta sia nullo. Invece, farei in modo che la raccolta sia inizializzata nel costruttore o qualunque sia il caso.

+1

O anche fare l'inizializzazione nel getter di proprietà! –

+0

Hai perfettamente ragione, ma se Collection è un membro virtuale in una classe (diciamo una classe entity nhibernate). Quindi verrà visualizzato un avviso "Chiamata membro virtuale nel costruttore". Preferisco il sopra di questo avvertimento. – Calin

+0

@Calin: Si prega di fornire un blocco di codice molto semplice che riproduce l'avviso che si sta descrivendo perché ritengo che sia stato eseguito correttamente che non dovrebbe essere il caso. – jason

0

Il codice emetterà un'assegnazione inutile (di obj.Collection a se stesso) se obj.Collection non è nullo, ma a parte che è equivalente a quello originario.

Mi sembra soddisfacente se non lo si utilizza nelle sezioni critiche. Comunque è possibile che il compilatore possa ottimizzare il compito, ma non so se lo farebbe o meno.

Forse si sbaglia solo perché il codice originale è un modello così comune e semplice che sembra sbagliato modificarlo.

3

vuoi dire:

if (obj.Collection == null) 
    { 
     obj.Collection = new Collection(); 
    } 
obj.Collection.Add(something); 

Se è così, si può riscrivere come

(obj.Collection = (obj.Collection ?? new Collection())).Add(something); 
+0

Errore del compilatore, riprovare. – leppie

+0

'(obj.Collection ?? (obj.Collection = new Collection())). Aggiungi (qualcosa);' funzionerà comunque. – leppie

+0

Sì, l'ho capito poco dopo aver postato la risposta e corretta. – tenor

0

direi che dipende anche da ciò che il setter della proprietà Collection fa. Considerate questo:

public Collection Collection 
{ 
    get { return _collection; } 
    set 
    { 
     _collection = value; 
     Thread.Sleep(1000); // or some expensive real work 
    } 
} 

In questo caso, l'assegnazione obj.Collection = obj.Collection ?? new Collection() sarebbe davvero costoso.

Tuttavia, se è necessario creare una collezione "on demand", è comune l'uso di un modello simile nel getter proprietà, in questo modo:

public Collection Collection 
{ 
    get { return _collection ?? (_collection = new Collection()); } 
} 
Problemi correlati