Earlier, I was provided a concrete example of contravariance in the generic IComparable<T>
interface by Jon Skeet. This has, however, spawned yet another question. Why isn't the generic List<T>.Sort()
method able to infer the same information?
I've provided the referenced example here as the static Foo<T>()
method. You'll observe that this method is able to infer the type of T
and call CompareTo(Circle)
. List<ICircle>.Sort()
on the other hand is unable to infer the type of T
and so calls 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;
}
}
}