2009-04-10 27 views
7

ho scritto il seguente metodo per restituire un elenco di classi Unserializable (classi LINQ) da un elenco di classi Serializable (pocos):C#: parola chiave 'default' con i generici

List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList) 
{ 
    var tempList = new List<UnSerializableEntity>(); 
    entityList.ForEach(e => 
    { 
     if (e != null) 
     { 
      tempList.Add(ConvertFromSerializableToUnserializable(e)); 
     } 
    }); 
    return tempList; 
} 

Ora, ReSharper ha ' lamentati' su questa linea: if (e != null), e ha suggerito di cambiarlo a questo:

if (!Equals(e, default(SerializableEntity))) 

la mia domanda è quello di ciò che ha questo cambiamento effettivamente migliorato o impedito accada? e so che la parola chiave predefinita in questo contesto deve fare qualcosa con i generici, ma non sono sicuro di cosa rappresenti esattamente.

PS. UnSerializableEntity e SerializableEntity sono generici di classe.

risposta

13

Se SerializableEntity è un tipo di valore, non può mai essere null. Pertanto, il corpo dell'istruzione if verrà sempre eseguito perché sta verificando la ricerca di null. La parola chiave default restituirà il valore predefinito del tipo generico. Per i tipi di riferimento, il valore predefinito è null. Per i tipi di valore, è zero (o qualsiasi valore zero rappresenta per quel tipo di valore).

Se si desidera solo i tipi di riferimento come entità, è necessario impostare i vincoli sui parametri generici. Per esempio: la risposta

List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList) 
    where SerializableEntity : class 
+0

Ma la sua istruzione if ha verificato che il valore era _not_ null, quindi ciò significherebbe che sarebbe eseguire sempre? – sisve

+0

Il blocco "if" non verrà mai eseguito: i tipi di valore genereranno un'eccezione. –

+0

@Simon l'istruzione e! = Null e! Equals (e, default (SerializableEntity)) sono entrambi veri quando e non è null/default –

4

di Kent è preciso, ma per rispondere alla tua domanda più esplicitamente di ReSharper e perché si lamenta:

Nel caso di un tipo di riferimento (classe) un assegno di nulla sarebbe sufficiente, poiché è considerato il valore "predefinito" per un tipo di riferimento. Tuttavia, per un tipo di valore (come una struct), il "default" non sarà MAI null. Quindi, dal momento che SerializableEntity e UnSerializableEntity sono generici, è possibile specificarli come riferimento o tipi di valore, quindi il controllo null che stai facendo non è probabilmente quello che desideri. Quello che vorresti controllare è assicurarsi che il parametro sia qualcosa con cui vuoi davvero occuparti. Nel caso di un tipo di riferimento, non ti devi preoccupare di oggetti nulli. Nel caso di un tipo di valore, non ti devi preoccupare di un valore "azzerato".

Ad esempio: supponiamo che tu specifichi un DateTime per il tipo di dati che stai trattando. Vuoi davvero aggiungere DateTimes che non hanno alcun valore impostato? Il valore predefinito per DateTime è 1/1/0001, non null, quindi è necessario verificarlo utilizzando if (!Equals(e, default(SerializableEntity))) non if (e != null)

Problemi correlati