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;
}
Community
  • 1
  • 1

2 Answers2

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
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Hihi, even if you post before Jon, you don't get any +1's :) – D.R. Jul 30 '13 at 20:16
  • May I ask why my edit has been rejected in favor of roughly the same edit by yourself? : | – D.R. Jul 30 '13 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 Jul 30 '13 at 21:21
  • Ok, didn't know about that after reading http://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. Jul 30 '13 at 21:28
  • @D.R.: That page covers it pretty well. – Jon Skeet Jul 30 '13 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
D.R.
  • 20,268
  • 21
  • 102
  • 205
  • Your code does not even require a cast. b is already of type Derived so this makes no sense at all. – D.R. Jul 30 '13 at 20:31
  • BTW: This code does not reflect the code shown in the original question! – D.R. Jul 30 '13 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; – Superman Coding Jul 30 '13 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. Jul 30 '13 at 21:16