2

我正在尝试找出对通用对象列表进行排序的正确方法。我的数据结构的一个简单示例:

// The base class
public abstract class Item : IComparable<Item> {
    public enum Category { Hats, Shirts, ... }
    public Category category;

    public int CompareTo (Item that) {
       ...
    }
}

// One of several classes extending Item
public class Hat : Item {
    public int CompareTo (Hat that) {
       ...
    }
}

我有一个管理器类,它为每个扩展 Item 的类维护列表:

Dictionary<Item.Category, List<Item>> _items;

...

foreach (Item.Category category in Enum.GetValues(typeof(Item.Category))) {
    List<Item> list = _items[category];
    list.Sort();
}

我遇到的问题是,当我调用 时List<Item>.Sort(),它显然没有使用特定于类的CompareTo()函数。解决这个问题的正确方法是什么?

4

2 回答 2

1

问题是List<Item>.Sort()正在寻找IComparable<Item>派生类未实现的实现。您添加了一个与您的实现无关CompareTo(Hat hat)的方法,只是它们碰巧具有相同的名称。您可以制作虚拟并重载它,但是您必须更改覆盖的签名:IComparable<Item>CompareTo

// The base class
public abstract class Item : IComparable<Item> {
    public enum Category { Hats, Shirts, ... }
    public Category category;

    public virtual int CompareTo (Item that) {
       // default implementation
    }
}

// One of several classes extending Item
public class Hat : Item {
    public override int CompareTo (Item that) {
       // override for Hats - can Hats be compared to other Items?
    }
}

还要非常小心,您的 CompareTo 是对称且可传递的,否则您的排序将失败:

对称:如果 a < b 那么 b > a

传递:如果 a < b 且 b < c 则 a < c

我已经看到它的实现CompareTo不是传递的,而且很难诊断和修复。

您还应该花时间覆盖 Equals 和比较运算符

于 2013-05-23T03:11:49.283 回答
0

有没有理由你不能只使用 c# 自带的内置比较?

list.OrderByDescending(..)或者list.OrderBy(..)

如果你想选择使用,Icomparable那么你必须告诉它要比较什么。

list.Sort((x,y) => x.Category.CompareTo(y.Category));
于 2013-05-23T02:19:54.937 回答