CSharp - Reference Casting and Conversions

Introduction

An object reference can be:

  • Implicitly upcast to a base class reference
  • Explicitly downcast to a subclass reference

An upcast always succeeds; a downcast succeeds only if the object is suitably typed.

Suppose we have the following class

class Shape{
       public string Name;
}

class Circle : Shape   // inherits from Shape
{
       public long Radius;
}

class Square : Shape   // inherits from Shape
{
       public decimal Width;
}

Upcasting

The following code is doing upcasting.

Circle myCircle = new Circle();
Shape a = myCircle;              // Upcast

After the upcast, variable a still references the same Circle object as variable myCircle.

Console.WriteLine (a == myCircle);        // True

Although a and myCircle refer to the identical object, a has a more restrictive view on that object:

Console.WriteLine (a.Name);           // OK
Console.WriteLine (a.Radius);    // Error: Radius undefined

The last line generates a compile-time error because the variable a is of type Shape, even though it refers to an object of type Circle.

To get to its Radius field, you must downcast the Shape to a Circle.

Downcasting

The following code is doing a downcasting.

Circle myCircle = new Circle();
Shape a = myCircle;                      // Upcast
Circle s = (Circle)a;                  // Downcast
Console.WriteLine (s.Radius);   // <No error>
Console.WriteLine (s == a);          // True
Console.WriteLine (s == myCircle);       // True

A downcast requires an explicit cast because it can potentially fail at runtime:

Square h = new Square();
Shape a = h;               // Upcast always succeeds
Circle s = (Circle)a;        // Downcast fails: a is not a Circle

If a downcast fails, an InvalidCastException is thrown.

Related Topics

Quiz