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);