What is Upcasting and Downcasting in C# ?

Upcasting is basically an object creation mechanism by which we create objects by referring to their base class. We do this by replacing the sub-class name by the base-class name in the object definition. This particularly comes in handy when you know that a specialized object created will not necessarily use all the functions of a specialized sub-class has got to offer. So, replace a sub-class(inherited class) by a base-class and all you have done is Upcasting.


This concept can be well understood if we take an example. Lets suppose we have three classes. One parent or generalized class called the LIVING_THINGS and the two subclasses ANIMAL and BIRD which inherit from the former. The parent class or the baseclass has the function, say Born()and Die(). The specialized class have the functions, say Run() and Fly() for ANIMAL and BIRD respectively.

To create an ANIMAL and BIRD object you would usually use the syntax below:
  • ANIMAL animal = new ANIMAL();
  • BIRD bird = new BIRD();  
In the code above, the methods Run()and Fly() work perfectly with the objects created. This is the normal way you would use to create the objects. The reference used to create the object is exactly the same as the object type created during run-time. The methods of the subclass work just fine.

But, to create an Upcast, you would use the syntax below:
  • LIVING_THINGS animal = new ANIMAL();
In the code above, even though we have created an object of the type ANIMAL and BIRD, the reference used is actually of the base-class. Therefore the methods Run() and Fly() are not available to these objects. Instead only the functions available in the base-class such as Born() and Die() are available.

This can be useful if you want only basic functions available at the start and want to later convert these objects of their original types to make their specialized functions available. 

This can be done with the help of Downcasting. Downcasting can change the reference types of these objects to the specialized subclass to make available the functions which were not available otherwise. Watch the code below:
  • ANIMAL new_animal  = animal as ANIMAL;
In the above code, we created a new object and converted it to an ANIMAL type. It should be a good practice to actually check if the object to be converted supports the conversion. This can be done with the help of the is keyword

if (animal is ANIMAL)
{
     ANIMAL new_animal  = animal as ANIMAL;
     new_animal.Run( );
}

With the help of Downcasting, we restored all the functions and properties that the ANIMAL object should have. Now it behaves as a proper ANIMAL object.