The definition System.Linq.ILookUp reads
interface ILookup : IEnumerable>, IEnumerable {
int Coun
Tracking the MSDN documentation, Covariance and Contravariance in Generics have been introduced in .NET Framework 4 Prior to that, there was IEnumerable
since the .NET Framework 2.0 up to .NET Framework 3.5. Then in .NET Framework 4.0 we can see IEnumerable
with type parameter T
as covariance.
IGrouping
and ILookup
have existed since .NET Framework 3.5. In .NET Framework 4.0 the former has been updated to IGrouping
but the latter has been omitted without specifying the reason.
TKey
can't be covariant since implementations of Contains(TKey)
and this[TKey]
prevent that.
With regard to TElement
the issue is not clear. I don't believe that designers just missed it. Perhaps cause lies in the plans for the future. Or they wanted to prevent something like the below, but I don't know why:
string[] strings = new[] {"a", "a", "b", "b", "b", "c"};
ILookup lookup = strings.ToLookup(s => s); // Valid.
ILookup lookup = strings.ToLookup(s => s); // Now invalid, but would correct if TElement was covariant (out TElement).
There are also other authors, that pay attention to that issue:
ToLookup:
One slightly odd point to note is that while IGrouping is covariant in TKey and TElement, ILookup is invariant in both of its type parameters. While TKey has to be invariant, it would be reasonable for TElement to be covariant