consider the following basic class layout:
public class Base : IComparable<Base>
{
public int CompareTo(Base other)
{
//Do comparison
}
}
public class Derived : Base, IComparable<Derived>
{
public int CompareTo(Derived other)
{
//Do comparison
}
}
public class BaseComparer : IComparer<Base>
{
public int Compare(Base x, Base y)
{
return x.CompareTo(y);
}
}
and then using those as follows:
List<Base> thingies = new List<Base>
{
new Base(),
new Derived(),
new Derived()
};
thingies.Sort(new BaseComparer());
I was expecting the Comparer to be calling the Derived.CompareTo method in those situations where both it’s x and y parameters are Derived instances.
However, this is not the case and Base.CompareTo is called instead and I keep wondering why. I can’t seem to deduct this behaviour with my basic understanding of the overload resolution rules as described in the C# language specification.
Can someone shed some light on this for me?
Baseknows nothing of its derived classes – so inBasethere’s only oneCompareTomethod, and that gets called unconditionally.The point is that overload resolution happens at compile time where there’s no information about the actual type of
Basereferences available. You need to override the method inDerived, not overload it:And additionally mark the
Base.CompareTomethodvirtual.Notice that this doesn’t implement
IComparable<Derived>any more. You can also do this, but for your purpose that’s unrelated.