Crea una instancia de objetos nulos con un operador de unión nula

12

Considere el siguiente escenario típico:

if(myObject == null) {
    myObject = new myClass();
}

Me pregunto qué se piensa de la siguiente sustitución utilizando el operador de fusión nula:

myObject = myObject ?? new myClass();

No estoy seguro de si debería usar el segundo formulario. Parece una buena forma abreviada, pero la construcción myObject = myObject al principio parece que podría ser un poco de olor de código.

¿Es esto algo razonable de hacer, o hay una mejor abreviatura que me estoy perdiendo? O tal vez, "¡Son tres líneas, superarlo!"?

Editar: Como se ha mencionado, tal vez llamar a esto un escenario típico es una exageración. Por lo general, encuentro esta situación cuando estoy recuperando una entidad de una base de datos que tiene una propiedad de tipo de referencia secundaria que puede o no haber sido completada todavía:

myClass myObject = myClassService.getById(id);
myObject.myChildObject = myObject.myChildObject ?? new myChildClass();
    
pregunta grin0048 22.08.2013 - 18:35

4 respuestas

16

Uso el operador de fusión nula todo el tiempo. Me gusta su concisión.

Este operador me parece de naturaleza similar al operador ternario (A? B: C). Se requiere un poco de práctica antes de que la lectura sea una segunda naturaleza, pero una vez que estás acostumbrado a ella, siento que la legibilidad mejora en las versiones a mano.

Además, la situación que describe es solo una situación en la que el operador es útil. También es útil reemplazar construcciones como esta:

if (value != null)
{
    return value;
}
else
{ 
    return otherValue;
}

o

return value != null ? value : otherValue;

con

return value ?? otherValue;
    
respondido por el 17 of 26 22.08.2013 - 18:40
2
  

Lo que me pregunto específicamente es usar el operador para establecer un objeto a sí mismo a menos que sea nulo.

El ?? operator se denomina operador de unión nula y se utiliza para definir un valor predeterminado para los tipos de valor anulable o los tipos de referencia. Devuelve el operando de la izquierda si el operando no es nulo; de lo contrario, devuelve el operando correcto.

myObject = myObject ?? new myObject(); - instantiate default value of object

Más detalles y ejemplo de código sobre el operador de unión nula - artículo de MSDN .

Si comprueba la condición more than nullable , como alternativa puede usar el operador ternario.

Operador ternario

También puede consultar ?: Operador . Se llama operador ternario o condicional . El operador condicional (? :) devuelve uno de los dos valores dependiendo del valor de una expresión booleana.

  

Un tipo anulable puede contener un valor, o puede estar indefinido. Los ?? operador define el valor predeterminado que se devolverá cuando se asigna un tipo anulable a un tipo no anulable. Si intenta asignar un tipo de valor anulable a un tipo de valor no anulable sin utilizar el? operador, generará un error en tiempo de compilación. Si utiliza una conversión y el tipo de valor que acepta valores null no está definido actualmente, se generará una excepción InvalidOperationException.

Un ejemplo de código de MSDN -?: Operator (C # Reference) :

int? input = Convert.ToInt32(Console.ReadLine());
string classify;

// ?: conditional operator.
classify = (input.HasValue) ? ((input < 0) ? "negative" : "positive") : "undefined";
    
respondido por el EL Yusubov 22.08.2013 - 18:52
2

No creo que ese escenario sea (o al menos debería ser) típico.

Si desea que el valor predeterminado de algún campo no sea null , configúrelo en el inicializador de campo:

myClass myObject = new myClass();

O, si la inicialización es más complicada, configúrela en el constructor.

Si desea crear myClass solo cuando realmente lo necesita (por ejemplo, porque su creación lleva mucho tiempo), puede usar Lazy<T> :

Lazy<myClass> myObject = new Lazy<myClass>();

(Esto llama al constructor predeterminado. Si la inicialización es más complicada, pase lambda que crea myClass al constructor Lazy<T> ).

Para acceder al valor, use myObject.Value , que llamará a la inicialización si es la primera vez que accede a myObject.Value .

    
respondido por el svick 22.08.2013 - 20:19
1

Me gusta especialmente usar ?? junto con parámetros de método opcionales. Limito la necesidad de sobrecargas y me aseguro de que la cosa tenga un valor.

public void DoSomething (MyClass thing1 = null) {
    thing1 = thing1 ?? new MyClass();
}
    
respondido por el radarbob 26.08.2013 - 14:31

Lea otras preguntas en las etiquetas