2012-08-09 66 views
3

早些时候,我在Jon Skeet的通用接口IComparable<T>中提供了一个反例的具体例子。但是,这又产生了另一个问题。为什么通用的List<T>.Sort()方法能够推断出相同的信息?为什么列表<IShape> .Sort()调用CompareTo(Object)而不是CompareTo(Shape)?

我在这里提供了引用的例子作为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; 
     } 
    } 
} 

回答

5

列出的是ICircle列表,而不是Circle列表。 ICircle不实现IComparable<Circle>IComparable<ICircle>(或任何其他IComparable接口。您放入列表中的所有项目确实实现了IComparer<Circle>Circle s,但您可以轻松地将项目放入执行的ICircle中并实施没有IComparable接口可言。

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

+0

Servy,好像列表的.sort()接受了IComparable/ICompar在幕后也能够进入。嗯,我现在想知道这是否与where子句是限制而不是必需类型有关。这意味着该示例可能实际上不会表现出反转现象。 – blf 2012-08-09 15:55:34