Interesting Generics/Inheritance Problem

Greetings all. I am trying to do something with generics and inheritance that seems it *should* work, but it just doesn't.

I have 2 class, Child, and the class it inherits from, Parent
I also have 2 collections, ChildCollection, and it's parent, ParentCollection
I am trying to do a downcast of ParentCollection to ChildCollection, but it just won't work. The code:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Parent { }
class Child : Parent { }

class ParentCollection<TParentType>
where TParentType : Parent
{ }

class ChildCollection : ParentCollection<Child>
{ }

class Program
{
static void Main(string[] args)
{
// This cast works absolutely fine
ChildCollection children = (ChildCollection)new ParentCollection<Child>();

// This cast, however, does not work.
ChildCollection others = (ChildCollection)new ParentCollection<Parent>();
}
}
}

It seems the second cast *should* work. ChildCollection inherits from ParentCollection, and Child inherits from Parent. You can cast a Parent to a Child. So why would a ParentCollection of type Parent not be cast to a ChildCollection

Any suggestions would be of great appreciation!! Thanks.


Answer this question

Interesting Generics/Inheritance Problem

  • Mark3947387

    I think you're looking at the inner type.

    ParentCollection<Parent>() != ParentCollection<Child>

    Nor is ParentCollection<Parent> inheriting ParentCollection<Child>

    The type ParentCollection<T1> is completely different from ParentCollection<T2> because the bucket's types are different. That type of casting isn't supported, and if it were.. it would probably be horrible on runtimes.

    Use a Factory Pattern to generate those collections.

    If the above doesn't make sense..
    A *collection* of Child isn't inherited *collection* of Parent. Child may inherit from Parent, but the actual type you're casting is "ParentCollection<Parent>". The reason ChildCollection children = (ChildCollection)new ParentCollection<Child>(); works is because ChildCollection inherits the base ParentCollection<Child>.


  • Andrea C

    To add a bit more rigor, ChildCollection inherits from ParentCollection<Child>.

    The second cast is the same as casting from ParentCollection<Parent> to ParentCollection<Child> (once you get this cast, the second cast to ChildCollection is trivial).

    I can't give a solid reason why it can't be supported in theory. But the interpretation I make is that ParentCollection<Child> does not inherit from ParentCollection<Parent>, therefore you can't cast between them.


  • Interesting Generics/Inheritance Problem