views:

108

answers:

3

Why do I get an InvalidCastException when trying to do this?

throw (ArgumentNullException)(new Exception("errormessage", null));

This is a simplified version of the following function.

public static void Require<T>(bool assertion, string message, Exception innerException) where T: Exception
    {
        if (!assertion)
        {
            throw (T)(new Exception(message, innerException));
        }
    }

The complete error message is:

System.InvalidCastException : Unable to cast object of type 'System.Exception' to type 'System.ArgumentNullException'.

+5  A: 

I have the impression that you are instantiating a base class and trying to cast it as a derived class. I don't think you are able to do this, as Exception is more "generic" than ArgumentNullException. You could do it the other way around though.

Wagner Silveira
Exactly. You can create a `NullReferenceException` and then cast it into an `Exception`, but you can't create an `Exception` and then cast it into a `NullReferenceException`.
zneak
That's correct. `Exception` is the base, `ArgumentNullException` is the child.
Steven Sudit
Umm... obvious :-) Thanks, it's a bit late here...
Dave
A: 

System.Exception is not the object you're casting to; it's that simple. Throw an exception of the different type directly if you want to raise that type.

Tahbaza
+1  A: 

You may want to try this instead:

public static void Require<T>(bool assertion, string message,
    Exception innerException) where T: Exception
{
    if (!assertion)
    {
        throw (Exception) System.Activator.CreateInstance(
            typeof(T), message, innerException);
    }
}
TrueWill
That gives me a "System.Reflection.AmbiguousMatchException : Ambiguous match found."
Dave
Works for me under .NET 4.0; tested in LINQPad 4 with a custom Exception descendant passed for T. Just tried it again with the following and it worked:Require<ArgumentNullException>(false, "test", new InvalidOperationException());
TrueWill
Just tried it under .NET 3.5 in VS2008; worked there too.
TrueWill