2010-03-30 13 views
10

¿Crees que C# admitirá algo como ?? = operator?¿Qué piensas sobre el operador ?? = en C#?

lugar de esto:

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

Podría ser posible escribir:

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

Ahora, yo podría usar (pero me parece que no está bien legible):

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

Eso sería genial! No estoy seguro de si lo admite ... ¡pero sí, me gusta! – Zoidberg

+0

Esta sugerencia de idea hace que mis partes de Ruby vibren. (Ver el operador Ruby '|| ='.) –

Respuesta

4

Siempre he querido algo como esto. Lo usaría mucho más a menudo que el ?? por sí mismo.

Lo que REALMENTE quiero es una forma de operador que le permita desreferenciar el objeto solo si no es nulo. Para reemplazar esto:

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

con algo como esto:

int count = list??.Count : 0 

cual sería especialmente útil para mí con largas cadenas de referencias (mal diseño, lo sé), pero por ejemplo

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

Esto no es posible actualmente con ?? porque solo puede decir "asignar a foo, o una alternativa si nulo" pero no "asignar a una propiedad de foo, o una alternativa si es nula. "

+0

Aunque estoy de acuerdo, creo que esto va en contra de la forma en que C# funciona en general. Me recuerda mucho más a los lenguajes de paso de mensajes como Obj-C, donde [list count]; devolvería null en lugar de disparar un error de excepción nulo. En C#, hace que la sintaxis sea mucho más confusa, especialmente porque en este caso casi siempre querrías usarla. – Jess

+0

por supuesto estoy de acuerdo, como cualquier cosa, puede ser peligroso en las manos equivocadas. De ninguna manera sugiero que esto sustituya el manejo de errores simplemente ignorando todas las referencias nulas. Pero hay algunos casos en que null es perfectamente aceptable, y usted tiene un valor alternativo válido para usar en ese caso. – Tesserex

+5

Esta es una característica solicitada con frecuencia. Lo estamos considerando. –

3

Me gusta, es una manera bonita y concisa de expresar una expresión de carga lenta. El que se agregue o no al idioma es otra cosa, como Eric Lippert loves to point out, las nuevas funciones requieren una gran cantidad de trabajo para implementar y, como tales, deben contribuir con un significativo neto positivo al idioma para poder ser incluidas.

+3

De hecho, no veo un gran beneficio aquí. Estoy un poco sorprendido de que un operador de "nulo que se combina con asignación" no se haya agregado cuando ?? fue agregado, pero realmente no agrega mucha potencia. –

16

Personalmente creo que sólo la segunda expansión tiene sentido (en términos de mantener a lo largo de la misma línea que += etc):

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

pero para ser honesto me parece un poco innecesario. La gente generalmente "obtiene" i += 5;, pero tiende a tener un problema con nulo-coalescente (??). Agregue un operador de asignación nulo-coalescente y ... bueno, no veo que termine bien.

Personalmente estoy a favor del código original:

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

también - tener en cuenta: en todos los demás +=, -= etc - el lado derecho es siempre evaluados. En este caso, no sería (en algunos casos). Eso agrega aún más confusión. Con lo que quiero decir:

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

Estoy de acuerdo. Es una elección entre la velocidad de escritura y la legibilidad. La legibilidad gana todo el tiempo. –

+3

Estoy de acuerdo en que la legibilidad es muy valiosa, pero me parece que el operador ?? = es bastante fácil de entender (por otra parte, me gusta Haskell, así que tal vez estoy acostumbrado a operadores arbitrarios). Pero no creo que el segundo ejemplo de Marc sea muy bueno. No debería ejecutar el código crítico como un efecto secundario de a = = de todos modos, por lo que es muy artificial. – CodexArcanum

4

Un truco que encontré en algún lugar aquí en stackoverflow era hacer algo como esto ...

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

... es posible que pueda utilizar eval perezoso similar en su código.