Home » c# » downcast and upcast

downcast and upcast

Posted by: admin November 29, 2017 Leave a comment

Questions:

I am new to C# (and OOP). When I have some code like the following:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

Question 1: If I have other code that does this:

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

Here Employee is a Manager, but when I cast it like that to an Employee it means I am upcasting it?

Question 2:

When I have several Employee class objects and some but not all of them are Manager‘s, how can I downcast them where possible?

Answers:
  1. That is correct. When you do that you are casting it it into an “employee” object, so that means you cannot access anything manager specific.

  2. Downcasting is where you take a base class and then try and turn it into a more specific class. This can be accomplished with using is and an explicit cast like this:

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

or with the as operator like this:

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

If anything is unclear I’ll be happy to correct it!

Questions:
Answers:

Upcasting (using (Employee)someInstance) is generally easy as the compiler can tell you at compile time if a type is derived from another.

Downcasting however has to be done at run time generally as the compiler may not always know whether the instance in question is of the type given. C# provides two operators for this – is which tells you if the downcast works, and return true/false. And as which attempts to do the cast and returns the correct type if possible, or null if not.

To test if an employee is a manager:

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

You can also use this

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");

Questions:
Answers:

In case you need to check each of the Employee object whether it is a Manager object, use the OfType method:

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}

Questions:
Answers:
  • Upcasting is an operation that creates a base class reference from a subclass reference. (subclass -> superclass) (i.e. Manager -> Employee)
  • downcasting is an operation that creates a subclass reference from a base class reference. (superclass -> subclass) (i.e. Employee -> Manager)

In your case

Employee emp = (Employee)mgr; //mgr is Manager

you are doing an upcasting.

An upcast always succeeds unlike a downcast that requires an explicit cast because it can potentially fail at runtime.(InvalidCastException).

C# offers two operators to avoid this exception to be thrown:

Starting from:

Employee e = new Employee();

First:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

Second:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

Warnign: When you do an upcast you can only access to the superclass’ methods, properties etc…