2011-01-23 4 views
7

Así insteed de la escritura:¿Qué pasa con el ?? operador que se utiliza como esto:

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

pensé de escribir:

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

En cierto modo se siente mal, sobre todo esta parte "obj.Collection = obj.Collection .. . "

¿Qué piensan?

Regards,

+4

¿Por qué se siente mal? – alexn

+0

Me parece bien – Vadim

+4

¿Cuál es el problema? ¿Tienes un problema con 'x = x + 1;'? –

Respuesta

15

Si tuviera que elegir entre estos dos bloques de código, usaría el primero. Es más legible y es un patrón común. ?? es útil en escenarios en los que necesita establecer un valor predeterminado (por ejemplo, DateTime date = nullableDateTimeInstance ?? defaultDate;).

Pero francamente, trataría de no terminar en una situación en la que quiero agregar a la colección y es posible que la colección sea nula. En cambio, me aseguraré de que la colección se inicialice en el constructor o en cualquier caso.

+1

¡O incluso hacer la inicialización en el getter de la propiedad! –

+0

Tiene mucha razón, pero si Collection es un miembro virtual de una clase (digamos una clase de entidad nhibernate). Luego terminará con una advertencia "llamada de miembro virtual en el constructor". Prefiero lo de arriba luego esta advertencia. – Calin

+0

@Calin: proporcione un bloque de código muy simple que reproduzca la advertencia que está describiendo porque creo que hecho correctamente no debería ser el caso. – jason

0

El código emitirá una asignación innecesaria (de obj.Collection a sí mismo) si obj.Collection no es nulo, pero aparte de que es equivalente a la original.

Me parece bien siempre que no lo utilice en las secciones de tiempo crítico. De todos modos, es posible que el compilador optimice la tarea, pero no sé si lo hará o no.

Quizás solo se sienta mal porque el código original es un patrón tan simple y común que se siente mal cambiarlo.

3

Qué quiere decir:

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

Si es así, puede volver a escribir como

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

Error del compilador, inténtelo de nuevo. – leppie

+0

'(obj.Collection ?? (obj.Collection = new Collection())). Agregar (algo);' funcionará sin embargo. – leppie

+0

Sí, me di cuenta de que poco después de publicar la respuesta y la corrigí. – tenor

0

yo diría que también depende de lo que el colocador de la propiedad Collection. Considere esto:

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

En este caso, la asignación obj.Collection = obj.Collection ?? new Collection() sería muy costoso.

Sin embargo, si usted necesita para crear una colección "a la carta", es común el uso de un patrón similar en la propiedad de captador, así:

public Collection Collection 
{ 
    get { return _collection ?? (_collection = new Collection()); } 
} 
Cuestiones relacionadas