NullReferenceException from a cast?

Just to show that no matter how experienced you are as a programmer, you can still get blind-sided by stupidly simple things sometimes, here's my tale of woe.

In one of my apps, I had code similar to the following:

try  
{
    (T)foo;
}
catch (InvalidCastException)  
{
    return default(T);
}

This is part of a generic method, where T can be any type (unconstrained). On the surface, it looks like I have my bases covered: if for some reason foo can't be cast to whatever type T represents, I'll just return the default for that type. Only, I missed one stupid little thing: if foo is null and T is a type that can't be null, then and only then, a NullReferenceException is raised instead of InvalidCastException.

The solution, of course, is to check for null first:

if (foo == null)  
{
    return default(T);
}

try  
{
    (T)foo;
}
catch (InvalidCastException)  
{
    return default(T);
}

Or, you can add an additional catch:

try  
{
    (T)foo;
}
catch (Exception e) when (e is NullReferenceException || e is InvalidCastException)  
{
    return default(T);
}

Long and short, never assume you know everything. I generally try to be very measured about my expertise, anyways, but this one really made me feel like a noob.

UPDATE

Another solution was proposed in the comments:

if (foo is T)  
    return (T)foo;
return default;  

I'm actually fond of the terseness of this version, and it seems to handle all the scenarios well.

comments powered by Disqus