Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#3.5

Generic Casting of .NET objects with a useful error message

0.00/5 (No votes)
30 Jan 2011CPOL 12.5K  
Use an extension method that applies to any object to Cast to other types
Problem

Often in code, we need to cast an object of one type to another at run-time, for example:

Customer customer = myObject as Customer;
// Or...
int number = (int) myObject;


However, if we forget to add the neccessary code to check that the object is of the expected type to be converted, we end up with the following error message(s) that do not help to determine WHY the cast failed:

Specified cast is not valid.

or
Object reference not set to an instance of an object.


Solution

Use an extension method on the Object class to perform a cast on any object in code and at run-time be assured that casting the wrong type will give us a useful error message to help solve the problem. For example:

Customer customer = myObject.CastTo<customer>();


An invalid cast results in an InvalidCastException error message that tells us why a cast failed:

"Expected object 'Joe Bloggs' to be of type MyCompany.Customer. Actual type is MyCompany.Manager."


The code for the Cast extension method is as follows:

XML
/// <summary>
/// Extension methods for the <c>object</c> class.
/// </summary>
/// <remarks>
/// Works only in .NET 3.5+
/// </remarks>
public static class ObjectExtensions
{
    /// <summary>
    /// Casts the supplied object to the value or reference type <c>T</c>, throwing an <c>InvalidCastException</c> with a useful message if the object is not of type <c>T</c>.
    /// </summary>
        /// <remarks>
        /// 'CastTo' name is used instead of simply 'Cast' to avoid clashes with LINQ extension methods with the same name.
        /// </remarks>
    /// <param name="input">Object to be cast.</param>
    /// <exception cref="InvalidCastException">Thrown if <paramref name="input"/> is not of type <c>T</c>.</exception>
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="input"/> is null.</exception>
    /// <returns>Object cast to of type <c>T</c>.</returns>
    public static T CastTo<T>(this object input)
    {
        T output;
        if (input != null)
        {
            if (input is T)
            {
                output = (T) input;
            }
            else
            {
                string message = String.Format("Expected object '{0}' to be of type {1}. Actual type is {2}", input.ToString(), typeof(T).Name, input.GetType().Name);
                throw new InvalidCastException(message);
            }
        }
        else
        {
            throw new ArgumentNullException("input");
        }
        return output;
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)