8

Say I have several derived classes whose base class is a generic class. Each derived class inherit the base class with a specific type override(but all types are also derived from a single base type).

For example:

I have a base row class

class RowBase
{
    //some properties and abstract methods
}

And I have two specific row classes that are derived from the row base class

class SpecificRow1 : RowBase
{
    //some extra properties and overrides
}

class SpecificRow2 : RowBase
{
    //some extra properties and overrides
}

Then I have a second base class that is a generic class which contains a collection of derived classes from RowBase

class SomeBase<T> where T : RowBase
{
    ICollection<T> Collection { get; set; }
    //some other properties and abstract methods
}

Then I have two classes that derive from SomeBase but are using different specific row class

class SomeClass1 : SomeBase<SpecificRow1>
{
     //some properties and overrides
}

class SomeClass2 : SomeBase<SpecificRow2>
{
     //some properties and overrides
}

Now that in my main or a bigger scope, I want to create a list/collection that consist both SomeClass1 and SomeClass2 objects. Like

ICollection<???> CombinedCollection = new ...
CombinedCollection.Add(new SomeClass1())
CombinedCollection.Add(new SomeClass2())
.
.
.
//add more objects and do something about the collection
.
.
.

The question is: is it possible to have such collection? If it is possible, how can I achieve this? If no, what can be an alternative way?

noddy
  • 83
  • 1
  • 4

1 Answers1

9

This can be done with the help of Covariance and Contravariance.

Add a new interface that and make the T parameter covariant (using the out keyword):

interface ISomeRow<out T> where T : RowBase
{
}

SomeBase should inherit that interface like this:

class SomeBase<T> : ISomeRow<T> where T : RowBase
{
    //some other properties and abstract methods
}

Then, the following will work:

List<ISomeRow<RowBase>> myList = new List<ISomeRow<RowBase>>();
myList.Add(new SomeClass1());
myList.Add(new SomeClass2());

Hope this is what you're looking for :)

danijelk
  • 6,749
  • 2
  • 16
  • 11
Blachshma
  • 17,097
  • 4
  • 58
  • 72
  • Aha, Interface! That's what I'm missing. Thanks! – noddy Nov 08 '12 at 19:51
  • 1
    This may have gone beyond my question but what if I have method that has a parameter of the generic type T and I want to call it when I loop the myList collection. In this case, I can't declare the type T covariant. So does that mean I can't do it at all? – noddy Nov 08 '12 at 23:23