C# – Casting and Reference Conversions

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