iComparable接口工作

时间:2016-03-19 07:28:58

标签: c# icomparable

我创建了一个带有iComparable接口的Customer类。

public class Customer: IComparable<Customer>
{
    public int ID {set; get;}
    public string Name {set; get;}
    public int Salary {set; get;}

    public int CompareTo(Customer obj)
    {
      if (this.Salary > obj.Salary)
          return 1;
        else if
            (this.Salary < obj.Salary)
            return -1;
        else
            return 0;
     }

}

在主程序中,我创建了一个客户列表,并添加了三个客户。

List<Customer> ListCust = new List<Customer>(); 
ListCust.Add(Cust1);
ListCust.Add(Cust2);
ListCust.Add(Cust3);

然后我对列表进行排序。

ListCust.Sort();

我的问题是这种排序方法如何选择Customer类的“CompareTo”部分。最初,当我试图在没有iComparable接口的情况下对其进行排序时,它给了我无效的操作错误。

以下问题是为什么我只是在没有iComparable接口的客户类中制作“CompareTo”方法并使其工作?

3 个答案:

答案 0 :(得分:2)

.NET无法&#34;只是&#34;对你的Customer对象进行排序是因为它无法猜测你想要对它们进行排序的方式:按工资,名字,姓氏,第一次下单等等。

但是,您可以通过三种不同的方式实现IComparable,从而使其发挥作用:

  • Pass a separate IComparer<Customer>实施 - 这可让您将比较逻辑移至单独的类,并根据情况应用不同的比较逻辑。
  • Pass a Comparison<Customer>代表 - 与上述相同,但现在您不需要单独的课程;这使您可以在lambda中提供比较逻辑。
  • 使用LINQ&#39; OrderBy代替 - 与上述类似,但为您提供了其他功能(过滤,投影,分组等)。

答案 1 :(得分:2)

Sort方法检查type参数是否实现IComparable。如果是,则该方法将列表中的每个项目转换为IComparable。这样的事情:(可能不是他们实际上这样做了,但你明白了。)

foreach (T item in this) {
    if (item is IComparable) {
        var castedItem = (IComparable)item;
        // do other things with castedItem
    } else {
        throw new InvalidOperationException("Sorting is not supported");
    }
}

因此,如果您未实现IComparable,则item is IComparable的计算结果为false,这就是为什么会抛出InvalidOperationException

因此,最终的原因是......

  

源代码不会检查您是否使用CompareTo方法。它只是检查您是否已实现接口。

答案 2 :(得分:0)

查看Sort方法的MSDN上的文档,其中显示

  

当comparer为null时抛出InvalidOperationException,并且默认比较器Comparer.Default找不到IComparable通用接口的实现或类型T的IComparable接口。

它是这样设计的。

相关问题