【问题标题】:Sorting Generic Lists with CompareTo使用 CompareTo 对通用列表进行排序
【发布时间】:2013-05-23 02:02:31
【问题描述】:

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

// 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&lt;Item&gt;.Sort() 时,它显然没有使用特定于类的CompareTo() 函数。解决这个问题的正确方法是什么?

【问题讨论】:

    标签: c# list sorting generics compareto


    【解决方案1】:

    问题是List&lt;Item&gt;.Sort() 正在寻找您的派生类未实现的IComparable&lt;Item&gt; 的实现。您添加了一个CompareTo(Hat hat) 方法,它与您的IComparable&lt;Item&gt; 实现没有任何关系,只是它们恰好具有相同的名称。您可以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 a

    传递:如果 a

    我见过CompareTo 的实现不具有传递性,而且很难诊断和修复。

    你也应该花时间去override Equals and the comparison operators

    【讨论】:

    • 非常感谢,这正是我正在寻找的解决方案,但无法弄清楚:)。完美运行!
    【解决方案2】:

    你有什么理由不能只使用 c# 自带的内置 compare 吗?

    list.OrderByDescending(..)list.OrderBy(..)

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

    list.Sort((x,y) => x.Category.CompareTo(y.Category));
    

    【讨论】:

    • 每个类都有自己在 CompareTo 中实现的排序逻辑,所以我认为我不能使用 OrderByDescending/OrderBy 来实现。
    • 不,你不能,我只是好奇,因为你没有发布排序逻辑,如果它只是通用排序。但是当你像我的例子一样传递什么参数来使用 lambda 排序时它应该可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多