Common Error – The difference between explicit and safe casts

In this post I’m going to cover a mistake I’ve seen quite often and which can lead to those ugly ‘Object reference not set to an instance of an object’ exceptions.

Here’s the question.  What’s the difference between the following 2 code snippets?

var result = controller.Login() as ViewResult;
var result = (ViewResult)controller.Login();

While watching one of the videos from Mix 09 I saw a rather famous developer use the first type of cast when he was clearly looking for the behaviour of the second.  (I’m not going to mention who it was)

So what’s the difference?  If the object being returned from the Login method call (which is an ActionResult in this case) is indeed an instance of the ViewResult class, both snippets will behave exactly the same.  However, if the cast is invalid (if the object returned is a RedirectToRouteResult, for example) the first snippet will set the result object to null, while the second snippet will throw an InvalidCastException.

Bottom line – if you’re expecting an object to be of a specific type, do an explicit cast (the second snippet).  If you’re unsure of the type of the object, either check the type or do a safe cast (the first snippet) and check if the result is null.

I actually use this behaviour quite often when doing TDD with MVC – the first test I write for an action is usually to check the value being returned.

[Test]
public void LoginActionShouldReturnLoginView()
{
    var result = controller.Login() as ViewResult;

    Assert.IsNotNull(result);
    Assert.AreEqual("Login", result.ViewName);
}

If I was testing a different part of the behaviour I would simply do an explicit cast.