我正在查看IOrderedEnumerable的声明,我很惊讶它在TElement类型参数中不是协变的。
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable
{
IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
}
它没有变成协变的原因是什么?
答案 0 :(得分:3)
这是一个疏忽,并且已在.NET Core中修复。这是关闭的issue,这里是pull request修复它。
我认为它没有得到完整.NET版本的修复,因为这是一个重大改变。例如(想法来自这个answer,这是关于另一个重大改变,但也适用于此):
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");
}
}
然后你打电话
Derived d = new Derived();
d.DoSomething(new List<string>().OrderBy(c => c));
如果IOrderedEnumerable
不是协变的,则会调用Base
方法。现在假设我们将其改为协变。当我们下次编译此代码时,会突然调用Derived
方法。