【问题标题】:iComparable Interface WorkingsiComparable 接口工作
【发布时间】:2016-03-19 07:28:58
【问题描述】:

我创建了一个带有 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”方法并使其工作?

【问题讨论】:

    标签: c# icomparable


    【解决方案1】:

    .NET 无法“仅”对您的 Customer 对象进行排序的原因是因为它无法猜测您希望以何种方式对它们进行排序:按薪水、按名字、按姓氏、按时间下了他们的第一个订单,等等。

    但是,您可以通过三种不同的方式在不实现 IComparable 的情况下使其工作:

    • Pass a separate IComparer&lt;Customer&gt; implementation - 这让您可以将比较逻辑移动到单独的类中,并根据情况应用不同的比较逻辑。
    • Pass a Comparison&lt;Customer&gt;delegate - 与上面相同,但现在您不需要单独的类;这让您可以在 lambda 中提供比较逻辑。
    • 改用 LINQ 的 OrderBy - 与上面类似,但提供了额外的功能(过滤、投影、分组等)

    【讨论】:

    • 谢谢。对于我的第一个问题,我是否正确地说 List 集合中的 sort 方法寻找 iComparable 的 CompareTo 方法的实现?
    • @user3186277 最终,是的,尽管它不直接这样做。它尝试通过Comparer&lt;Customer&gt;.Default 获取默认比较器,它首先尝试IComparable&lt;Customer&gt;,然后尝试非通用IComparable。如果两次尝试都失败,排序会抛出异常。
    【解决方案2】:

    Sort 方法检查类型参数是否实现了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");
        }
    }
    

    因此,如果您不实施 IComparableitem is IComparable 的计算结果为 false,这就是抛出 InvalidOperationException 的原因。

    因此,最终的原因是……

    源代码不会检查您是否有CompareTo 方法。它只是检查你是否实现了接口。

    【讨论】:

      【解决方案3】:

      查看MSDNSort 方法的文档,上面写着

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

      它是这样设计的。

      【讨论】:

        猜你喜欢
        • 2010-10-29
        • 1970-01-01
        • 2011-05-10
        • 1970-01-01
        • 2011-01-25
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多