我创建了一个带有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”方法并使其工作?
答案 0 :(得分:2)
.NET无法&#34;只是&#34;对你的Customer
对象进行排序是因为它无法猜测你想要对它们进行排序的方式:按工资,名字,姓氏,第一次下单等等。
但是,您可以通过三种不同的方式实现IComparable
,从而使其发挥作用:
IComparer<Customer>
实施 - 这可让您将比较逻辑移至单独的类,并根据情况应用不同的比较逻辑。Comparison<Customer>
代表 - 与上述相同,但现在您不需要单独的课程;这使您可以在lambda中提供比较逻辑。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接口。
它是这样设计的。