Down-Casting:

* Using the derived / child class object reference "to find base / parent class object reference" (i.e. using outer container location to find the inner container location). * In other words, finding the address / reference of base / parent class object by using the existing reference variable of derived / child class object is known as down-casting. * It is an implicit operation.
Note: Naturally child class inherits from other class or Object class. Hence down-casting will never create "exception i.e. runtime error".

Example:

public partial class Test : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
    {
        B refB = new B();
        Response.Write(refB.x); // -1
        A refA = refB; // down-casting
        Response.Write(refA.x); // 1
    }
}
public class A
{ public int x = 1;
}
public class B : A
{ public int x = -1;
}

Things to Keep in Mind:

* The reference variable holds the class name and address of same class object (as given in the RAM architecture above). * We know that, during casting operation (up-casting and down-casting) usually reference variable is used to get the address of object present in Heap memory. Whenever casting operation comes into picture, the actual address in reference variable points to the object created in RAM must be kept in mind rather than the codes present under the class.

Observation:

* At the 3rd line of code in Page_Load method, reference variable (refA) of class A object is created with the help of reference variable (refB) of class B object (where A is the base class and B is the derived class). * During compilation when CLR executes the 3rd line of code, it reads the address present in refA reference variable and look for B class object inside 0x777. After it finds one, it creates another reference variable in stack as refA and stores the address of A class object in it.
[Q] What is the purpose of casting operation? [A] Since global variables present in class A and B are having same name, down-casting is recommended to access the actual address of objects of respective classes. In case of different global variables in all classes, there is no requirement of casting operation. Just the most derived class object reference variable can be used to access the member of any class. (Refer (i) "hiding base class members" and (ii) "new" keyword topics to understand this scenario in detail)

Up-Casting:

* Using the base / parent class object reference "to find child / derived class object reference" (i.e. using inner container location to find the outer container location). * In other words, finding the address / reference of derived / base class object by using the existing reference variable of derived / child class object is known as up-casting. * It is an explicit operation.

Example:

Observation:

* The name of reference type variable is used with o prefix so that it makes sense that it holds the address of object of particular class. (Refer Naming Conventions Topic for more details) * In the example code an alternative way of down-casting is also represented wherein "(Class Name)" is not mandatory because down-casting is usually more often used in real time applications and development. Hence down-casting doesn't need extra codes to be written where as it is mandatory for up-casting. * Lines 7 and 8 are representing 2 ways of up-casting are shown. * For ease of understanding let us consider the line 7 which represents up-casting operation (i.e. oB = (B) oA;). From this line of code let us understand how the up-casting is done by CLR during execution, > oA is used to get the address of object of class A. > CLR searches for object of type "B" (the type mentioned in brackets in code) inside the address given by oA reference variable. > After finding the type B object, its address is stored in reference variable which is capable of holding address of type B only. * It is so important to note that at line 9, new object of class A is created (which is not inheriting from any class) and its address is stored in the existing reference variable of type A. Thus the old address is replaced with new address. * Since newly created A class object doesn't inherit from any class, up-casting operation to find its parent class will cause exception. Because CLR will try to look into the RAM memory hoping that B type object may be present and when it doesn't find it, it have no other option other than to give an exception. * Hence in the example code except the last line of code, all other codes' execution is successfully completed. Since exception occurred when executing the last line, RAM memory allocated for the program is withdrawn / erased immediately.

Example:

Let us look into a simple example where down-casting is not necessary.
public partial class Temp : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        B b = new B();
        Response.Write(b.x); // 1
        Response.Write(b.y); // 100
        /*y is still accessible from object of class B since
         there is only one y variable in the whole object*/
    }
}
public class A
{ public int x = 1; }
public class B : A
{ public int y = 100; }
* In above example, accessing variable 'y' doesn't require down-casting since there is only one y in the whole object. * CLR always look into the address / reference variable of the existing object including all the derived / child objects inside same object. * Down-casting is possible in this example but it's simply not required. Note: Object oriented programming languages are designed in a way to imitate real life objects/things. Hence always try to compare real life examples with OOPL concepts for much better clarity