Polymorphism in generic type parameters

Viewed 1834

I am trying to use polymorphism in generic type parameters in C#. I have reviewed several other questions on SO (1, 2, 3, 4, 5, 6), but I'm still not clear why this doesn't work (or if it's even allowed).

Background

I have the following classes:

public class Base { }

public class Derived<T> : Base { }

public class Foo { }

and an instance of my derived generic type:

var derived = new Derived<Foo>();

The basics

The following statements are all true:

derived is Object

derived is Base

derived is Derived<Foo>

The problem

When I try to use my derived class as a type parameter in another generic type I get some unexpected behavior. Given the following lazy instance:

var lazy = new Lazy<Derived<Foo>>();

The following is true:

lazy is Lazy<Derived<Foo>>

But these are false when I expected them to be true:

lazy is Lazy<Object>

lazy is Lazy<Base>

Why is this? Should they be true or have I misunderstood how generics work?

2 Answers

Basically, there's property of generic type called invariance.

IList<string> derivedList = new List<string>();    
IList<object> baseList = derivedList;

The above code won't compile.

The polymorph rules when playing with inheritance applied to classes, not type parameters. C# loosen up the invariance rule with covariance and contravariance. But again, just don't treat type parameter as Type itself, it is more a parameter.

Related