<p>I didn't attend PDC 2008, but I heard some news that C# 4.0 is announced to support Generic covariance and contra-variance. That is, <code>List&lt;string&gt;</code> can be assigned to <code>List&lt;object&gt;</code>. How could that be?</p>

<p>In Jon Skeet's book <strong><em>C# in Depth</em></strong>, it is explained why C# generics doesn't support covariance and contra-variance. It is mainly for writing secure code. Now, C# 4.0 changed to support them. Would it bring chaos?</p>

<p>Anybody know the details about C# 4.0 can give some explanation?</p>

Variance will only be supported in a
safe
way - in fact, using the abilities that the CLR already has. So the examples I give in the book of trying to use a
```
List<Banana>
```
as a
```
List<Fruit>
```
(or whatever it was) still won't work - but a few other scenarios will.
Firstly, it will only be supported for interfaces and delegates.
Secondly, it requires the author of the interface/delegate to decorate the type parameters as
```
in
```
(for contravariance) or
```
out
```
(for covariance). The most obvious example is
```
IEnumerable<T>
```
which only ever lets you take values "out" of it - it doesn't let you add new ones. That will become
```
IEnumerable<out T>
```
. That doesn't hurt type safety at all, but lets you return an
```
IEnumerable<string>
```
from a method declared to return
```
IEnumerable<object>
```
for instance.
Contravariance is harder to give concrete examples for using interfaces, but it's easy with a delegate. Consider
```
Action<T>
```
- that just represents a method which takes a
```
T
```
parameter. It would be nice to be able to convert seamlessly use an
```
Action<object>
```
as an
```
Action<string>
```
- any method which takes an
```
object
```
parameter is going to be fine when it's presented with a
```
string
```
instead. Of course, C# 2 already has covariance and contravariance of delegates to some extent, but via an actual conversion from one delegate type to another (creating a new instance) - see P141-144 for examples. C# 4 will make this more generic, and (I believe) will avoid creating a new instance for the conversion. (It'll be a reference conversion instead.)
Hope this clears it up a bit - please let me know if it doesn't make sense!