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

Mehrdad Afshari
- 414,610
- 91
- 852
- 789

UserControl
- 14,766
- 20
- 100
- 187
3 Answers
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
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.

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