2009-04-10 17 views
7

He escrito el siguiente método para devolver una lista de clases Unserializable (clases de LINQ) de una lista de clases serializables (POCOs):C#: palabra clave 'por defecto' con los genéricos

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

Ahora, ReSharper tiene ' quejado' sobre esta línea: if (e != null), y sugirió que cambiarlo a esto:

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

Mi pregunta es lo que ha hecho este cambio mejorado o impedido suceda? y sé que la palabra clave predeterminada en este contexto tiene que hacer algo con los genéricos, pero no estoy seguro de lo que representa exactamente.

PS. UnSerializableEntity y SerializableEntity son genéricos de clase.

Respuesta

13

Si SerializableEntity es un tipo de valor, nunca puede ser null. Por lo tanto, el cuerpo de su declaración if siempre se ejecutará porque está buscando null. La palabra clave default devolverá el valor predeterminado del tipo genérico. Para los tipos de referencia, el valor predeterminado es null. Para tipos de valor, es cero (o lo que sea cero representa para ese tipo de valor).

Si solo desea tipos de referencia como entidades, debe establecer restricciones en sus parámetros genéricos. Por ejemplo: la respuesta

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

Pero su instrucción if verificó que el valor era _not_ nulo, entonces eso significaría que lo haría siempre ejecutar? – sisve

+0

El bloque "if" nunca se ejecutará: los tipos de valor arrojarán una excepción. –

+0

@Simon la declaración e! = Null y! Iguales (e, predeterminado (SerializableEntity)) son verdaderos cuando e no es nulo/predeterminado –

4

de Kent es exacta, pero para responder a su pregunta más explícitamente sobre ReSharper y por qué se queja:

En el caso de un tipo de referencia (clase) un cheque por nula sería suficiente, ya que se considera el valor "predeterminado" para un tipo de referencia. Sin embargo, para un tipo de valor (como una estructura), el "valor predeterminado" NUNCA será nulo. Por lo tanto, dado que su SerializableEntity y UnSerializableEntity son genéricos, puede especificar que sean tipos de referencia o de valor, por lo que la verificación nula de sus acciones probablemente no sea la que desea. Lo que debería verificar es asegurarse de que el parámetro sea algo que realmente le interese. En el caso de un tipo de referencia, no desea preocuparse por objetos nulos. En el caso de un tipo de valor, no desea preocuparse por un valor "cero".

Por ejemplo: Supongamos que especifica un DateTime para que sea el tipo de datos con el que está tratando. ¿De verdad quieres agregar DateTimes que no tenga ningún valor establecido? El valor predeterminado para DateTime es 1/1/0001, no nulo, por lo que necesitaría verificarlo usando if (!Equals(e, default(SerializableEntity))) no if (e != null)