downcast and upcast
Asked Answered
C

6

107

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?

Clemen answered 6/10, 2009 at 8:3 Comment(1)
Upcasting can be done without explicit cast. So Employee emp= mgr; should suffice.Aha
H
112
  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!

Hottempered answered 6/10, 2009 at 8:9 Comment(4)
I need example to know what is Downcasting ?Clemen
Avoid redefining well-established terms: “boxing”, in the context of OOP and C#, means something rather different (= wrapping a value type object into a reference). Also, your example could (and should) use the as operator instead of is, followed by a cast.Ammonium
I stand corrected on the first point, and i changed the second half of my answer to show both ways of doing it.Hottempered
Your first statement ("...casting [an instance of Manager class] into an "employee" object [..] means you cannot access anything manager specific") is not completely accurate. In OP's example, if Employee has a virtual member that is overridden in Manager, the CLR will call the Manager implementation, notwithstanding the cast. From the MSDN article on polymorphism in C#: "When a derived class overrides a virtual member, that member is called even when an instance of that class is being accessed as an instance of the base class." The example provided by MSDN is almost identical.Isley
E
52

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");
Emanative answered 6/10, 2009 at 8:10 Comment(2)
Isn't Employee m = new Manager(); polymorphism? (I am still studying OOP now, and I came across upcasting/downcasting and polymorphism) I find them very similar, any pointers?Hapsburg
yes, it is. They are different in this way. Polymorphism is a general term for things that could be used interchangeably and is an ability, while up and downcasting is doing of referring to it in one way or another. Adjective vs verb.Emanative
C
23
  • 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 

Warning: When you do an upcast you can only access to the superclass' methods, properties etc...

Cuckooflower answered 28/9, 2015 at 13:48 Comment(0)
B
7

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..
}
Briareus answered 22/1, 2014 at 18:5 Comment(0)
D
3

Answer 1 : Yes it called upcasting but the way you do it is not modern way. Upcasting can be performed implicitly you don't need any conversion. So just writing Employee emp = mgr; is enough for upcasting.

Answer 2 : If you create object of Manager class we can say that manager is an employee. Because class Manager : Employee depicts Is-A relationship between Employee Class and Manager Class. So we can say that every manager is an employee.

But if we create object of Employee class we can not say that this employee is manager because class Employee is a class which is not inheriting any other class. So you can not directly downcast that Employee Class object to Manager Class object.

So answer is, if you want to downcast from Employee Class object to Manager Class object, first you must have object of Manager Class first then you can upcast it and then you can downcast it.

Diphthong answered 3/5, 2019 at 5:44 Comment(0)
L
0

Upcasting and Downcasting:

Upcasting: Casting from Derived-Class to Base Class Downcasting: Casting from Base Class to Derived Class

Let's understand the same as an example:

Consider two classes Shape as My parent class and Circle as a Derived class, defined as follows:

class Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
}

class Circle : Shape
{
    public int Radius { get; set; }
    public bool FillColor { get; set; }
}

Upcasting:

Shape s = new Shape();

Circle c= s;

Both c and s are referencing to the same memory location, but both of them have different views i.e using "c" reference you can access all the properties of the base class and derived class as well but using "s" reference you can access properties of the only parent class.

A practical example of upcasting is Stream class which is baseclass of all types of stream reader of .net framework:

StreamReader reader = new StreamReader(new FileStreamReader());

here, FileStreamReader() is upcasted to streadm reder.

Downcasting:

Shape s = new Circle(); here as explained above, view of s is the only parent, in order to make it for both parent and a child we need to downcast it

var c = (Circle) s;

The practical example of Downcasting is button class of WPF.

Lurlinelusa answered 26/1, 2018 at 20:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.