6

IEnumerable<T>, IComparable<T> and a few more are now type-variant. IList<T>, ICollection<T> and many others aren't. Why?

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
UserControl
  • 14,766
  • 20
  • 100
  • 187

3 Answers3

11

.NET Framework 4.0 introduces safe co/contra-variance. IList<T> and ICollection<T> have T both in input and output positions while IEnumerable<T> has T only in output positions and IComparable<T> has T only in input positions.

Assume IList<T> supported type variance:

static void FailingMethod(IList<object> list) {
    list[0] = 5;
}

static void Test() {
    var a = new List<string>();
    a[0] = "hello";
    FailingMethod(a); // if it was variant, this method call would be unsafe
}
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • Thanks! Looks like using indexers makes any class non-variant. But ICollection<> has T only in input parameters. – UserControl May 31 '09 at 19:27
  • No, it's not related to indexers in general. It depends on the parameter and return type of indexers (and existence of get/set accessors), just like any other method or property. You might have an indexer like: T this[int index] { get { return x[index]; } } and without a set accessor, it could be variant. – Mehrdad Afshari May 31 '09 at 19:31
2

See also: What C# 4.0 covariance doesn't do

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

Anders Hejlseberg has a brief, but illuminating discussion that describes co/contravariance in his talk, "The Future of C#." His discussion on covariance and contravariance starts at 50 minutes and 17 seconds into the presentation.

http://channel9.msdn.com/pdc2008/TL16/

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501