2010-03-30 12 views
10

Pensi che C# supporterà qualcosa come ?? = operatore?Cosa ne pensi di ?? = operator in C#?

Invece di questo:

if (list == null) 
    list = new List<int>(); 

Potrebbe essere possibile scrivere:

list ??= new List<int>(); 

Ora, ho potuto usare (ma mi sembra non ben leggibile):

list = list ?? new List<int>(); 
+0

che sarebbe cool! Non sono sicuro che lo supporti ... ma sì, mi piace! – Zoidberg

+0

Questa idea suggerisce che le mie parti di Ruby facciano un formicolio caldo. (Vedi l'operatore Ruby '|| ='.) –

risposta

4

Ho sempre desiderato qualcosa di simile. Lo userei molto più spesso dello ?? da solo.

quello che voglio, però, è una forma di operatore che permette di dereference l'oggetto solo se non nullo. Per sostituire questo:

int count = (list != null)? list.Count : 0 

con qualcosa di simile:

int count = list??.Count : 0 

Che sarebbe particolarmente utile per me con lunghe catene di riferimenti (cattiva progettazione, lo so), ma per esempio

int count = foo??.bar??.baz??.list??.Count : 0 

Questo non è attualmente possibile con ?? perché si può solo dire "assegnare a foo, o un'alternativa se null" ma non "assegnare a una proprietà di foo, o un'alternativa se nullo. "

+0

Mentre sono d'accordo, penso che ciò vada contro il modo in cui C# funziona in generale. Mi ricorda molto più i linguaggi di passaggio dei messaggi come Obj-C, dove [elenco conta]; restituirebbe null invece di lanciare un errore di eccezione nullo. In C#, rende la sintassi molto più confusa, soprattutto perché in questo caso si vorrebbe quasi sempre usarlo. – Jess

+0

ovviamente sono d'accordo, come qualsiasi cosa, può essere pericoloso nelle mani sbagliate. Non sto suggerendo in alcun modo che questo sostituto per la gestione degli errori semplicemente ignorando tutti i riferimenti null. Ma ci sono alcuni casi in cui null è perfettamente accettabile e in questo caso si ha un valore alternativo valido da utilizzare. – Tesserex

+5

Questa è una funzionalità richiesta frequentemente. Lo stiamo considerando. –

3

Mi piace - è un modo carino e sintetico per esprimere un'espressione pigra. Se aggiungere o meno alla lingua è un'altra cosa - come Eric Lippert loves to point out, le nuove funzionalità richiedono una quantità significativa di lavoro da implementare e come tali devono contribuire con un significativo netto positivo alla lingua per poter essere incluse.

+3

In effetti, non sto vedendo un enorme vantaggio qui. Sono leggermente sorpreso che un operatore "null coalescing with assignment" non sia stato aggiunto quando ?? è stato aggiunto, ma in realtà non aggiunge molto potere. –

16

Personalmente penso che solo la seconda espansione ha un senso (in termini di mantenimento lungo la stessa linea += ecc):

list = list ?? new List<int>(); 

Ma ad essere onesti lo trovo un po 'inutile. Le persone di solito "ottengono" i += 5;, ma tendono ad avere un problema con coalizione nulla (??). Aggiungi un operatore con assegnazione a coalizione nulla e ... beh, non vedo che finisca bene.

Personalmente prediligo il codice originale:

if(list == null) { list = new List<int>(); } 
.... 

Inoltre - considerare: in tutti gli altri +=, -= ecc - il lato di destra è sempre valutata. In questo caso non sarebbe (in alcuni casi). Ciò aggiunge ancora più confusione. Con ciò intendo:

i += SomethingCriticalThatMustBeCalled(); // fine - always runs 
j ??= SomethingElseCriticalThatMustBeCalled(); // is this run? if j != null? 
+1

Sono d'accordo. È una scelta tra velocità di scrittura e leggibilità. La leggibilità vince sempre. –

+3

Concordo sul fatto che la leggibilità sia molto preziosa, ma trovo che l'operatore ?? = sia abbastanza facile da comprendere (quindi, ancora una volta, mi piace haskell, quindi forse sono abituato ad operatori arbitrari). Ma non penso che il secondo esempio di Marc sia molto buono. Non dovresti eseguire codice critico come un effetto collaterale di + = in ogni caso, quindi è molto artificioso. – CodexArcanum

4

Un trucco che ho trovato da qualche parte qui su StackOverflow è stato quello di fare qualcosa di simile ...

private List<string> myList; 
public List<string> MyProp 
{ 
    get { return myList ?? (myList= new List<string>()); } 
} 

... è forse in grado di utilizzare simili eval pigro nel codice.