Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code work for different types?

Tags:

c#

generics

I am working on some class room examples. This code works but I do not see why it works. I know that there is a generic type and that class implements Item but Item is just another class. Why would this code allow a int and double into the same list.

I am sure that it has to do with the Generic but why I am not really certain.

Question: Why does this code allow two different types into the same list?

Class definitions:

public class Item<T> : Item
{
}

public class Item
{
}

Code:

static void Main(string[] args)
{
    var list = new List<Item>();

    list.Add(new Item<int>());
    list.Add(new Item<double>());
}
like image 578
Doug Hauf Avatar asked Apr 21 '14 22:04

Doug Hauf


4 Answers

Your confusion here is stemming from the fact that you have two generic types, not one. The first is the generic list, which you already understand. The second is the generic Item class:

public class Item<T> : Item

The definition of this class states that Item<T> always inherits Item, regardless of what type T is. This means, that when you create a List<Item>...

var list = new List<Item>();

... you can add any Item<T> to it, as any Item<T> is an Item.

like image 138
Ant P Avatar answered Nov 14 '22 00:11

Ant P


Why would this code allow a int and double into the same list.

It works because you store Item, not Item<T>.

This equivalent code makes it easier to see:

//list.Add(new Item<int>());
Item item1 = new Item<int>();   // implicit conversion from Item<int> to Item
list.Add(item1);

//list.Add(new Item<double>());
Item item2 = new Item<double>();
list.Add(item2);
like image 29
Henk Holterman Avatar answered Nov 14 '22 01:11

Henk Holterman


It works because Item<T> is an Item, so an Item<double> can be put in a List<Item>, as can an Item<int>

Part of the confusion may stem from the fact that you're using a similar type name (Item and Item<T>) for different classes. Although in your case one inherits from the other, there's no built-in connection between a class and a generic version of that class.

like image 25
D Stanley Avatar answered Nov 14 '22 00:11

D Stanley


The confusing thing in your example is that both the base and derived classes have the label "Item". However, with a few name changes, your code is equivalent to :

public class Pet {}
public class Dog : Pet {}
public class Cat : Pet {}

static void Main(string[] args)
{
    var list = new List<Pet>(); //  base type items

    list.Add(new Dog());
    list.Add(new Cat());
}

Even though two different types are being stored in the list, they are derived from the same base class. The key to understanding the code is that the List<> is a container for the base type, in this case "Pet" - and in your example the base type is "Item".

like image 1
Phillip Ngan Avatar answered Nov 14 '22 00:11

Phillip Ngan