CSharp/C# Tutorial - C# Cast






Casting and Reference Conversions

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 properly typed.

Upcasting

An upcast operation creates a base class reference from a subclass reference.

For example:


Product myProduct = new Product(); 
Item a = myProduct; // Upcast 

Product, DiscountProduct, Item are all defined in the previous section.

After the upcast, variable a still references the same Product object as variable myProduct.

The object being referenced is not itself altered or converted:


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

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


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

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

To get to its InStoreCount field, we have to downcast the Item to a Product.





Downcasting

A downcast operation creates a subclass reference from a base class reference.

For example:


Product myProduct = new Product(); 
Item a = myProduct; // Upcast 

Product s = (Product)a; // Downcast 

Console.WriteLine (s.InStoreCount); 
Console.WriteLine (s == a);         // True 
Console.WriteLine (s == myProduct); // True 

As with an upcast, only references are affected-not the underlying object.

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


DiscountProduct h = new DiscountProduct(); 
Item a = h; // Upcast always succeeds 
Product s = (Product)a; // Downcast fails: a is not a Product 

If a downcast fails, an InvalidCastException is thrown.





The as operator

The as operator performs a downcast that evaluates to null rather than throwing an exception if the downcast fails:


Item a = new Item(); 
Product s = a as Product; // s is null; no exception thrown 

This is useful when you're going to subsequently test whether the result is null:


if (s != null) {
   Console.WriteLine (s.InStoreCount); 
}