I\'m having a little trouble understanding how I would use covariance and contravariance in the real world.
So far, the only examples I\'ve seen have been the same o
class A {}
class B : A {}
public void SomeFunction()
{
var someListOfB = new List();
someListOfB.Add(new B());
someListOfB.Add(new B());
someListOfB.Add(new B());
SomeFunctionThatTakesA(someListOfB);
}
public void SomeFunctionThatTakesA(IEnumerable input)
{
// Before C# 4, you couldn't pass in List:
// cannot convert from
// 'System.Collections.Generic.List' to
// 'System.Collections.Generic.IEnumerable'
}
Basically whenever you had a function that takes an Enumerable of one type, you couldn't pass in an Enumerable of a derived type without explicitly casting it.
Just to warn you about a trap though:
var ListOfB = new List();
if(ListOfB is IEnumerable)
{
// In C# 4, this branch will
// execute...
Console.Write("It is A");
}
else if (ListOfB is IEnumerable)
{
// ...but in C# 3 and earlier,
// this one will execute instead.
Console.Write("It is B");
}
That is horrible code anyway, but it does exist and the changing behavior in C# 4 might introduce subtle and hard to find bugs if you use a construct like this.