2009-04-10 9 views
7

ich die folgende Methode geschrieben haben eine Liste von unserialisierbar Klassen (LINQ Klassen) aus einer Liste von Serializable Klassen (POCOs) zurückzukehren:C#: 'default' Schlüsselwort mit Generics

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

Jetzt, ReSharper hat ' beschwerten‘darüber: if (e != null), und schlug vor, es so zu ändern:

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

Meine Frage ist zu was diese Veränderung geschieht tatsächlich verbessert oder verhindert hat? und ich weiß, das Standard-Schlüsselwort in diesem Zusammenhang muss etwas mit Generika tun, aber ich bin mir nicht sicher, was es genau darstellt.

PS. UnSerializableEntity und SerializableEntity sind Klasse Generika.

Antwort

13

Wenn SerializableEntity ein Werttyp ist, kann es niemals null sein. Daher wird der Körper Ihrer if-Anweisung immer ausgeführt, da es auf null überprüft. Das Schlüsselwort default gibt den Standardwert des generischen Typs zurück. Für Referenztypen lautet der Standardwert null. Für Werttypen ist es Null (oder was auch immer Null für diesen Werttyp darstellt).

Wenn Sie Referenztypen nur als Entitäten verwenden möchten, sollten Sie Einschränkungen für Ihre generischen Parameter festlegen. Zum Beispiel:

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

Aber seine if-Anweisung überprüft, dass der Wert _not_ null war, würde also bedeuten, dass es wäre immer ausführen? – sisve

+0

Der "if" -Block wird niemals ausgeführt: Werttypen werden eine Ausnahme ausgelöst. –

+0

@Simon die Anweisung e! = Null und! Equals (e, default (SerializableEntity)) sind beide wahr, wenn e nicht null ist/default –

4

Kent Antwort richtig ist, aber Ihre Frage mehr explizit über ReSharper zu beantworten und warum es beschwert:

Im Fall eines Referenztypen (Klasse) eine Prüfung auf null würde genügen, da dies der "Standard" -Wert für einen Referenztyp ist. Bei einem Werttyp (z. B. einer Struktur) ist der Standardwert jedoch NULL. Da es sich bei SerializableEntity und UnSerializableEntity um Generics handelt, können Sie sie als Referenz- oder Werttypen angeben. Daher ist die von Ihnen gewünschte Null-Überprüfung wahrscheinlich nicht das, was Sie möchten. Was Sie überprüfen möchten, ist sicherzustellen, dass der Parameter etwas ist, mit dem Sie sich wirklich befassen möchten. Bei einem Referenztyp wollen Sie sich nicht mit Null-Objekten beschäftigen. Im Falle eines Werttyps möchten Sie sich nicht mit einem "nullten" Wert befassen.

Beispiel: Angenommen, Sie geben DateTime als den Datentyp an, mit dem Sie arbeiten. Möchten Sie wirklich DateTimes hinzufügen, für die kein Wert festgelegt wurde? Der Standardwert für eine DateTime ist 1/1/0001, nicht null, also müssten Sie dies überprüfen mit if (!Equals(e, default(SerializableEntity))) nicht if (e != null)