c# - 为什么 List<IShape>.Sort() 调用 CompareTo(Object) 而不是 CompareTo(Shape)?

标签 c# sorting contravariance compareto

早些时候,我在通用 IComparable<T> 中获得了逆变的具体示例Jon Skeet 的界面。然而,这又产生了另一个问题。为什么不是通用的 List<T>.Sort()方法能够推断出相同的信息?

我在这里提供了引用示例作为 static Foo<T>()方法。您会发现此方法能够推断出 T 的类型并调用CompareTo(Circle) . List<ICircle>.Sort()另一方面无法推断 T 的类型所以调用CompareTo(Object) .

using System;
using System.Collections.Generic;

namespace Testable
{
    public class Test
    {
        public static void Main()
        {
            List<ICircle> circles = new List<ICircle>();

            circles.Add(new Circle());
            circles.Add(new Circle());

            circles.Sort();

            Foo(new Circle(), new Circle());
        }

        public static void Foo<T>(IComparable<T> a, T b) where T : ICircle
        {
            a.CompareTo(b);
        }
    }

    public interface ICircle
    {
    }

    public class Circle :
    IComparable, IComparable<Circle>, ICircle
    {
        public Int32 CompareTo(Object other)
        {
            Console.WriteLine("Called CompareTo(Object)");
            return 0;
        }

        public Int32 CompareTo(Circle other)
        {
            Console.WriteLine("Called CompareTo(Circle)");
            return 0;
        }
    }
}

最佳答案

列表是ICircle的列表, 不是 Circle 的列表. ICircle没有实现 IComparable<Circle>IComparable<ICircle> (或任何其他 IComparable 接口(interface)。您放入列表中的所有项目都恰好实现了 IComparer<Circle> 并且是 Circle s,但是您可以轻松地将一个项目放入已实现的 ICircle 并实现根本没有 IComparable 接口(interface)。

Foo另一方面需要 IComparable<T>作为参数,所以你知道它实现了IComparable<T> .

关于c# - 为什么 List<IShape>.Sort() 调用 CompareTo(Object) 而不是 CompareTo(Shape)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11886976/

相关文章:

c# - 屏幕截图质量比正常差

python - Pandas sort_values 没有正确排序数字

Scala:将逆变类型作为隐式参数传递不会选择最近的父类(super class)型?

scala - 函数的参数类型是逆变的,返回类型是协变的

c# - Windows 服务 OnStop 等待完成处理

c# - 在 javascript 代码中调用 ASP 方法

c# - 部署和发布依赖于 SQL Server 的 WPF 应用程序

vba - 对工作簿中的所有工作表进行排序

令人头疼的 Javascript 数组排序

c# - 委托(delegate)方差规则的怪异示例