views:

793

answers:

2

I have written the following method to return a list of Unserializable classes (LINQ classes) from a list of Serializable classes (POCOs):

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

Now, Resharper has 'complained' about this line: if (e != null), and suggested to change it to this:

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

My question is to what has this change actually improved or prevented from happening? and I know the default keyword in this context has to do something with generics, but I'm not sure what it represents exactly.

PS. UnSerializableEntity and SerializableEntity are class generics.

+13  A: 

If SerializableEntity is a value type, it can never be null. Therefore, the body of your if statement will always execute because it is checking for null. The default keyword will return the default value of the generic type. For reference types, the default value is null. For value types, it is zero (or whatever zero represents for that value type).

If you only want reference types as entities, you should set constraints on your generic parameters. For example:

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

HTH, Kent

Kent Boogaart
But his if statement checked that the value was _not_ null, so would that mean that it would always execute?
Simon Svensson
The "if" block will never execute: value types will thrown an exception.
Joel Coehoorn
@Simon the statement e != null and !Equals(e, default(SerializableEntity)) are both true when e is not null/default
Arkain
@Joel, testing against `null` will not throw an exception if `e` is a value type. Is there some other exception that you're referring to?
bdukes
+3  A: 

Kent's response is accurate, but to answer your question more explicitly about Resharper and why it's complaining:

In the case of a reference type (class) a check for null would suffice, since that is considered the "default" value for a reference type. However, for a value type (such as a struct), the "default" will NEVER be null. Hence, since your SerializableEntity and UnSerializableEntity are generics, you can specify them to be either reference or value types, so the null check your doing is probably not what you want. What you would want to check is to make sure that the parameter is something that you really want to concern yourself with. In the case of a reference type, you don't want to concern yourself with null objects. In the case of a value type, you don't want to concern yourself with an "zeroed out" value.

For example: Say you specify a DateTime to be the data type you're dealing with. Do you really want to be adding DateTimes that do not have any value set? The default value for a DateTime is 1/1/0001, not null, so you would need to check for that using if (!Equals(e, default(SerializableEntity))) not if (e != null)

Joseph