2

I know there are already some questions posted related to this same topic, but I have seen different answers so I am quite confused on which answer is correct.

On the below link, people mentioned that downcasting is not possible Convert/Cast base type to Derived type

While on this link below, people mentioned that downcasting is possible only if the derived class is an instance of the base class downcast and upcast

I did a little experiment and implemented the downcasting on a mini project(C#) using direct casting, for example: DerivedClass dc = (DerivedClass) baseClass without checking whether or not DerivedClass is an instance of BaseClass, and to my surprise, it is working fine with no errors at all, so why people said downcasting is not possible?

So my question is, is downcasting really not possible? Why people seem to have different answers on this topic? after-all which one is the REAL answer? Could someone please explain this in more detail?

Sample code:

public class Order {  }

public class PurchaseOrder : Order { // some new properties here for PurchaseOrder}

public static PurchaseOrder GetOrder()
{
    Order order = new Order();
    return (PurchaseOrder)order;
}
3
  • 1
    The code you posted in your update compiles without error, but when run will fail with an InvalidCastException. Commented Jul 30, 2013 at 20:26
  • I've been using the above code for quite a long time, and I don't see any errors yet. so strange... Commented Jul 30, 2013 at 20:38
  • 1
    If you really used GetOrder() before it MUST have thrown an InvalidCastException.
    – D.R.
    Commented Jul 30, 2013 at 21:18

2 Answers 2

12

Downcasting isn't possible when the object isn't actually an instance of the type you're trying to convert to - if it's just an instance of the base class.

It is possible when it's an instance of the derived class already1.

For example, this is fine:

object x = "hello";
string y = (string) x;

Here the value of x is a reference to an instance of string, so downcasting to string is fine.

This is not fine:

object x = new object();
string y = (string) x; // Bang!

Here the value of x is a reference to an instance of object, so the cast fails.

EDIT: The code you've now included in the question is like my second example - you're creating an instance of just Order and trying to cast it to PurchaseOrder. That won't work - it isn't a PurchaseOrder. If you change it like this, however:

public static PurchaseOrder GetOrder()
{
    Order order = new PurchaseOrder();
    return (PurchaseOrder)order;
}

... it's fine. (It's odd code, but it works.)

See "Casting and type conversions" in MSDN for more information.


1 Or if you're trying to convert to some other interface or class in the object's actual type's hierarchy. For example, this is okay too:

object x = new MemoryStream();
Stream y = (Stream) x; // Stream is in the type hierarchy of MemoryStream
5
  • 2
    Hihi, even if you post before Jon, you don't get any +1's :)
    – D.R.
    Commented Jul 30, 2013 at 20:16
  • May I ask why my edit has been rejected in favor of roughly the same edit by yourself? : |
    – D.R.
    Commented Jul 30, 2013 at 21:17
  • @D.R.: Because it wasn't appropriate for you to make that edit - adding more material rather than just honing the existing material - whereas it's fine for the original author to do that.
    – Jon Skeet
    Commented Jul 30, 2013 at 21:21
  • Ok, didn't know about that after reading stackoverflow.com/help/privileges/edit - is there any additional meta-FAQ material I should know about, so I know when it's appropriate to make edits?
    – D.R.
    Commented Jul 30, 2013 at 21:28
  • @D.R.: That page covers it pretty well.
    – Jon Skeet
    Commented Jul 30, 2013 at 21:29
4

Downcasting is possible if you are sure about your type, this works fine:

class Base {}
class Derived : Base {}

Base b = new Derived();
Derived d = (Derived) b;

This does not work:

class Other : Base {}

Base b = new Other();
Derived d = (Derived) b; // InvalidCastException
4
  • Your code does not even require a cast. b is already of type Derived so this makes no sense at all.
    – D.R.
    Commented Jul 30, 2013 at 20:31
  • BTW: This code does not reflect the code shown in the original question!
    – D.R.
    Commented Jul 30, 2013 at 20:32
  • sorry, it was typo, here is the correct codes: class Base {} class Derived : Base {} Base b = new Base(); Derived d = (Derived) b; Commented Jul 30, 2013 at 21:14
  • That does not work. The object referenced by b is an object of type Base not an object of type Derived.
    – D.R.
    Commented Jul 30, 2013 at 21:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.