Today a friend of mine asked me how to cast from
List<> to a custom
MyCollection class, where
MyCollection is derived from
List<>. Is this
Let’s suppose we have the following class:
1 2 3 4
and we need a collection of instances of this class, for example using the
In order to improve readability, but also save time when writing code, we are often tempted to create a non-generic class implementing the list we need – even if we usually don’t really need such class
1 2 3
The problem arises when we use both the generic version and the custom version of the list in our code, and more specifically when we create an instance using the generic list and we need to pass this instance to a method expecting the custom version of the list:
1 2 3 4 5 6 7 8
The code above generates an error during compilation, whereas a direct cast
MyCollection generates a runtime exception:
1 2 3 4 5
The problem is that
List<MyClass> is a base class and
MyCollection is a
derived class, hence there is no way to explicitly perform the cast.
Let’s forget about lists and generics for a moment. We have to classes:
1 2 3 4 5 6 7 8 9
If I write the following code:
1 2 3 4 5 6
The last statement obviously causes a runtime exception, as a downcast from a base class to a derived class cannot be done.
1 2 3
The reason is that a derived class (usually) extends the base class by adding more state objects (i.e. data members). When we create an instance of a base class, its data members are allocated in memory, but of course data members of inherited classes are not allocated. So, downcasting from a base to a derived class is not possible because data members of the inherited class are not allocated.
But if we instantiate
MyDerivedClass the cast is allowed – in
other words downcasting is allowed only when the object to be cast is of the
same type as the type it’s being cast to:
1 2 3
myBaseClass, although being a variable of type
MyBaseClass, is a
reference to an instance of
In our problem,
MyCollection, so we are trying to cast an instance of a base class to an
instance of a derived class. It’s evident why the cast we want to do is not
So, is there a solution? If we think in terms of casting, the answer is NO. What we can do is a conversion.
The difference between cast and conversion is that the cast operates on the same object instance, whereas a conversion creates a new copy.
We might think about implementing a conversion operator, either implicit or explicit, for instance:
1 2 3 4 5 6 7 8
but it won’t work, as the compiler generates a
1 2 3
The reason why the compiler denies such conversion is that the explicit cast operator from a base to a derived class is automatically generated, and we can’t override it with a new conversion operator.
The only viable solutions are either defining a copy constructor or implementing a method in the derived class which converts the base class to an instance of the derived class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
In both cases, anyway, the conversion implies the creation of a new instance of the object to be converted.