Casting and Reference Conversions
An object reference can be implicitly upcast to base class or explicitly downcast to subclass.
Upcasting
- Create base class reference from a subclass reference.
- After the upcast the variable will reference the subclass variable.
- The difference is that the object will have restrictive views on properties.
Example
Stock fields and properties will not be accessed by the Asset class.
using System; namespace Rextester { public class Program { public static void Main(string[] args) { Stock msft = new Stock(); Asset a = msft; //Upcast //after the upcast, the two variables still reference the same Stock object Console.WriteLine (a == msft); // True Console.WriteLine (a.Name); Console.WriteLine (a.SharesOwned);//Error } } public class Asset { public string Name; } public class Stock : Asset { public long SharesOwned; } public class House : Asset { public decimal Mortgage; } }
Downcasting
- Creates a subclass reference from a base class reference.
- Requires an explicit cast because it can fail during runtime.
- InvalidCastException is thrown, if downcast fails.
using System; namespace Rextester { public class Program { public static void Main(string[] args) { Stock msft = new Stock(); Asset a = msft; //Upcast Stock s =(Stock)a; //Downcast //after the upcast, the two variables still reference the same Stock object Console.WriteLine (a == s); // True Console.WriteLine (msft == s); // True Console.WriteLine (a.Name); Console.WriteLine (s.SharesOwned); House h = new House(); Asset a2 = h; Stock s2 = (Stock)a2;// Error a2 is not an asset as it references to house object } } public class Asset { public string Name; } public class Stock : Asset { public long SharesOwned; } public class House : Asset { public decimal Mortgage; } }
The as operator
as operator performs downcast that evaluates to null rather than throwing exceptions.
Asset a = new Asset() Stock s = a as Stock;
It is better to test for null first than accessing object properties.
if ( s != null) Console.WriteLine (s.SharesOwned);
The as operator cannot perform custom conversions.
long x = 3 as long; // compile- time error
The is operator
Tests whether an object derives from a specified class. Often used to test before downcasting.
if (a is Stock) Console.WriteLine(((Stock)a).SharedOwned);