问题
I was Looking at the declaration of IOrderedEnumerable an I was suprised that it isn't covariant in it's TElement type parameter .
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable
{
IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
}
What's the reason for which it was not made covariant ?
回答1:
It's an oversight and that was fixed in .NET Core. Here is (closed) issue about that and here is pull request which fixes it.
It's not getting fixed in full .NET version I think because that's a breaking change. For example (idea is taken from this answer which is about another breaking change, but applies here too):
public class Base
{
public void DoSomething(IOrderedEnumerable<string> strings)
{
Console.WriteLine("Base");
}
}
public class Derived : Base
{
public void DoSomething(IOrderedEnumerable<object> objects)
{
Console.WriteLine("Derived");
}
}
Then you call
Derived d = new Derived();
d.DoSomething(new List<string>().OrderBy(c => c));
If IOrderedEnumerable
is not covariant - Base
method would be called. Now suppose we change that to covariant. When we next time compile this code, suddenly Derived
method is called.
来源:https://stackoverflow.com/questions/47728857/why-the-interface-iorderedenumerablet-isnt-covariant-in-t