Instantiating Null Objects con Null-Coalescing Operator

12

Considera il seguente scenario tipico:

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

Mi chiedo cosa si pensi della seguente sostituzione usando l'operatore a coalescenza nulla:

myObject = myObject ?? new myClass();

Non sono sicuro se dovrei usare il secondo modulo. Sembra una bella stenografia, ma il costrutto myObject = myObject all'inizio sembra che potrebbe essere un po 'un odore di codice.

È una cosa ragionevole da fare, o c'è una migliore abbreviazione che mi manca? O forse, "Sono tre righe, passaci sopra!"?

Modifica: Come è stato detto, forse definire questo uno scenario tipico è un'esagerazione. Di solito trovo che incontro questa situazione quando sto recuperando un'entità da un database che ha una proprietà del tipo di riferimento figlio che potrebbe essere popolata o meno:

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

4 risposte

16

Uso sempre l'operatore a coalescenza nulla. Mi piace la concisione di questo.

Trovo che questo operatore sia di natura simile all'operatore ternario (A? B: C). Ci vuole un po 'di pratica prima che la lettura di esso sia una seconda natura, ma una volta che ci si abitua, sento che la leggibilità migliora rispetto alle versioni a mano lunga.

Inoltre, la situazione che descrivi è solo uno scenario in cui l'operatore è utile. È anche utile per sostituire costrutti come questo:

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

o

return value != null ? value : otherValue;

con

return value ?? otherValue;
    
risposta data 22.08.2013 - 18:40
fonte
2

What I'm wondering about specifically is using the operator to set an object to itself unless it's null.

Il ?? operator è chiamato operatore a coalescenza nulla e viene utilizzato per definire un valore predefinito per tipi di valori o tipi di riferimento nullable. Restituisce l'operando di sinistra se l'operando non è nullo; altrimenti restituisce l'operando corretto.

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

Ulteriori dettagli e esempi di codice relativi all'operatore a coalescenza nulla - Articolo MSDN .

Se controlli la condizione more than nullable , come alternativa puoi usare l'operatore Ternario.

Operatore ternario

Puoi anche guardare ?: Operatore . Si chiama operatore Ternario o condizionale . L'operatore condizionale (? :) restituisce uno dei due valori in base al valore di un'espressione booleana.

A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type. If you try to assign a nullable value type to a non-nullable value type without using the ?? operator, you will generate a compile-time error. If you use a cast, and the nullable value type is currently undefined, an InvalidOperationException exception will be thrown.

Un esempio di codice da MSDN -?: Operatore (riferimento C #) :

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

// ?: conditional operator.
classify = (input.HasValue) ? ((input < 0) ? "negative" : "positive") : "undefined";
    
risposta data 22.08.2013 - 18:52
fonte
2

Non penso che lo scenario sia (o almeno dovrebbe essere) tipico.

Se vuoi che il valore predefinito di qualche campo non sia null , allora impostalo nel campo initializer:

myClass myObject = new myClass();

Oppure, se l'inizializzazione è più complicata, impostala nel costruttore.

Se vuoi creare myClass solo quando ne hai effettivamente bisogno (ad esempio perché la sua creazione richiede molto tempo), puoi usare Lazy<T> :

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

(Questo chiama il costruttore predefinito. Se l'inizializzazione è più complicata, passa lambda che crea myClass al costruttore Lazy<T> .)

Per accedere al valore, utilizza myObject.Value , che chiamerà l'inizializzazione se questa è la prima volta che accedi a myObject.Value .

    
risposta data 22.08.2013 - 20:19
fonte
1

In particolare mi piace usare ?? in combinazione con i parametri del metodo facoltativo. Limito la necessità di sovraccarichi e garantisco che la cosa abbia un valore.

public void DoSomething (MyClass thing1 = null) {
    thing1 = thing1 ?? new MyClass();
}
    
risposta data 26.08.2013 - 14:31
fonte

Leggi altre domande sui tag