两个接口都是用于比较对象大小。

IComparer

MSDN

主要用于比较两个对象并返回一个值。 提供了Compare方法,传入两个参数并返回一个值,通过返回值来表示两个对象之间的大小。 可以自定义比较对象大小的标准。

public int Compare(Object x, Object y)
{
    throw new NotImplementedException();
}

IComparable

MSDN

主要用于将当前实例与同一类型的另一个对象进行比较并返回一个值,用于表示当前实例在比较大对象的前面,后面还是同一位置。 提供CompareTo,有一个参数返回一个值,通过返回值来表示两个对象之间的大小。

public int CompareTo(object? other)
{
    throw new NotImplementedException();
}

通常,提供 IComparable 实现的类型也会实现 IEquatable 接口。 接口 IEquatable 定义 Equals 方法,该方法确定实现类型的实例的相等性。

含义
小于零 当前实例在排序顺序中位于CompareTo方法所指定的对象之前。
当前实例在排序顺序中与CompareTo方法参数指定的对象出现在同一位置。
大于零 当前实例位于排序顺序中由CompareTo方法自变量指定的对象之后。

IComparer和IComparable 在List.Sort中的应用

继承自IComparer接口的类如果需要使用自定义的比较方法需要显示定义:

IComparer TComparer = new T();并将TComparer传入到Sort方法中作为参数。

继承自IComparable接口的类,直接调用Sort方法即可。

MSDN注解:

此接口由值可以排序或排序的类型实现,并提供强类型比较方法,用于对泛型集合对象的成员进行排序。 例如,一个数字可以大于第二个数字,一个字符串可以按字母顺序显示在另一个字符串之前。 它要求实现类型定义一个 方法 , CompareTo(T)该方法指示当前实例在排序顺序中的位置是之前、之后还是与同一类型的第二个对象相同。 通常,不会直接从开发人员代码调用 方法。 相反,它由 和 Add等List.Sort()方法自动调用

List<Foo> foos = new List<Foo>
{
    new Foo { Id = 1, Name = "b" },
    new Foo { Id = 5, Name = "c" },
};
Console.WriteLine("\n------- 继承IComparer<Foo> 正序 -------\n");

IComparer<Foo> fooComparer = new Foo();
foos.Sort(fooComparer);

foos.ForEach
(
    p =>
    {
        Console.WriteLine($"继承IComparer<Foo> Id:{p.Id},Name:{p.Name}");
    }
);

Console.WriteLine("\n------- 继承IComparable<Foo> 倒序 -------\n");

foos.Sort();

foos.ForEach
(
    p =>
    {
        Console.WriteLine($"继承IComparable<Foo> Id:{p.Id},Name:{p.Name}");
    }
);