Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcasting a list of objects in C#

How can I downcast a list of objects so that each of the objects in the list is downcast to an object of a derived class?

This is the scenario.

I have a base class with a List of base items, and two classes inheriting from it:

public class BaseClass
{
    public List<BaseItem> items;
    protected BaseClass()
    {
        // some code to build list of items
    }
}
public class DerivedClass : BaseClass
{
    public DerivedClass : base() {}
}
public class AnotherDerivedClass : BaseClass
{
    public AnotherDerivedClass : base() {}
}

public class BaseItem {}
public class DerivedItem : BaseItem {}
public class AnotherDerivedItem : BaseItem {}

The idea is to not have to duplicate the code needed to build the list of items. The BaseItem has all the basic stuff I need, and I can always downcast BaseItem to one of the derived items.

The problem arises when I have a list of them. The List of BaseItem is declared in the BaseClass because all the derived classes have to have it. But when accessing it at runtime I can't seem to be able to downcast to the derived class.

like image 953
Farinha Avatar asked Mar 08 '11 14:03

Farinha


People also ask

Why downcasting is not allowed?

Downcasting is not allowed without an explicit type cast. The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class.

How do you downcast an object?

Downcasting is done using cast operator. To downcast an object safely, we need instanceof operator. If the real object doesn't match the type we downcast to, then ClassCastException will be thrown at runtime.

Why is downcasting used?

Downcasting is useful when the type of the value referenced by the Parent variable is known and often is used when passing a value as a parameter. In the below example, the method objectToString takes an Object parameter which is assumed to be of type String.

Is downcasting a code smell?

Downcasting is considered a code smell, and it is recommended to consider your design choices if you need to perform downcasting. You need to perform downcasting when you need to call subtype specific behaviour and all you have is an object of supertype.


1 Answers

Using LINQ:

    var baseList = new List<BaseClass>();
    var derivedList = baseList.Cast<DerivedClass>();

Note: Having to downcast usually is a 'smell' and indicates that the inheritance hierarchy is wrong, or wrongly implemented. The idea of having a base class is that you can treat all subclasses as superclass without having to downcast to individual subclass types.

Instead of Cast you might want to use OfType to 'fish out' certain derived classes from a collection of superclasses. But again, there should be no need to do that.

Ask yourself, why you need to have a subclass - maybe you need to move some functionality to base class?

like image 84
Jakub Konecki Avatar answered Nov 09 '22 11:11

Jakub Konecki