为什么接口IOrderedEnumerable <t>在T中不协变?

时间:2017-12-09 13:03:33

标签: c# covariance

我正在查看IOrderedEnumerable的声明,我很惊讶它在TElement类型参数中不是协变的。

public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable
{
    IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
}

它没有变成协变的原因是什么?

1 个答案:

答案 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方法。