views:

46

answers:

3
ArgumentException argumentException = (ArgumentException)new Exception();

throws:

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

Why can I not cast an Exception (less definition, I would think) to an ArgumentException (more definition, I would think)?

+5  A: 

That's like trying to do:

FileStream stream = (FileStream) new object();

What file would it read from or write to?

You can only cast a reference to a type if the actual object is that type or has that type in its hierarchy. So this will work:

Exception exception = new ArgumentException();
ArgumentException argumentException = (ArgumentException) exception;

and this will work too:

Exception exception = new ArgumentOutOfRangeException();
// An ArgumentOutOfRangeException *is* an ArgumentException
ArgumentException argumentException = (ArgumentException) exception;

but your example won't because an instance of just System.Exception isn't an instance of System.ArgumentException.

Note that this has nothing to do with exceptions, really - the same logic is applied for all reference types. (With value types there's also boxing/unboxing to consider. Oh, and there's also potentially user-defined conversions, e.g. from XElement to string - but we'll leave those out of it too for the moment.)

Jon Skeet
I like the `(FileStream)new object()` example. Demonstrates the point nicely.
Anthony Pegram
+4  A: 

Because you're creating an Exception object, not an Argument exception. You're trying to cast an object to a descendant of the type you're instantiating. You can do this:

Exception ex = new ArgumentException();

But you cannot do this:

ArgumentException ex = (ArgumentException)new Exception();
Adam Robinson
+1  A: 

Why can I not cast an Exception (less definition, I would think) to an ArgumentException (more definition, I would think)?

Because that additional information ("more definition") has to come from somewhere. You can only cast from base to derived when the base actually is a derived in disguise.

sbi