Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About Generics and Inheritance (forgive my bad title)

As I don't know how my problem is called, I cannot guarantee, that nobody has asked the same question recently or at all.

I did notice, however that there are quite a few threads with a similar title, but they don't seem to be relevant to my problem.

I have a custom list class, that implements Generics.

class MyList<T>
{
    public void add(T item) // adds an item to the list
    { /* code */ }
    public void add(MyList<T> list) // attaches an existing list to the end of the current one
    { /* code */ }
}

I also have the classes:

class Apple : Fruit

and

class Banana : Fruit

Now, comes the relevant code:

MyList<Fruit> fruitList = new MyList<Fruit>();
// fill fruitList

fruitList.add(new Apple()); // works, of course
fruitList.add(new Banana()); // works as well, of course

MyList<Apple> appleList = new MyList<Apple>();
// fill appleList

fruitList.add(appleList); // doesn't work. Why?

Even though appleList is a MyList(Of Apple) and Apple is Fruit, VisualStudio doesn't accept MyList(Of Apple) as argument, when MyList(Of Fruit) is asked.

However, if I were to declare the list like this:

MyList<object> fruitList = new MyList<object>();

Then everything works again. What exactly did I do wrong?

An answer would be much appreciated, and thank you for taking the time to read, even without answering.

like image 757
Nolonar Avatar asked Jan 26 '12 19:01

Nolonar


1 Answers

You're trying to use covariance.
.Net only supports generic variance on interfaces, so that won't work.

In addition, covariance only makes sense on immutable types.
Had it been possible to convert a MyList<Apple> to a MyList<Fruit>, you would then be able to add an Orange to the list, violating type safety.

Instead, you can make the method generic:

public void Add<U>(IList<U> list) where U : T
like image 53
SLaks Avatar answered Oct 29 '22 18:10

SLaks