如何对Collection <t>进行排序?</t>

时间:2012-02-16 21:43:49

标签: c# .net sorting

我有一个通用集合:

public Items : Collection<Object>
{
   protected override void InsertItem(int index, Object item)
   {
      base.InsertItem(index, item);
      ...
   }

   protected override void RemoveItem(int index)
   {
      base.RemoveItem(index);
      ...
   }

   protected override void SetItem(int index, Object item)
   {
      base.SetItem(index, item);
      ...
   }

   protected override void ClearItems()
   {
      base.ClearItems();
      ...
   }

现在我需要一种方法来对这个集合进行排序。

Bonus Chatter

我尝试将我的班级转换为使用List<T>而不是Collection<T>(因为Collection<T>不支持订单的概念)。然后允许调用Sort方法:

this.Items.Sort(SortCompareCallback);

protected virtual int SortCompareCallback(Object x, Object y)
{
   return OnCompareItems(new SortCompareEventArgs(x, y, this.sortColumnIndex, direction));
}

但是在修改列表时我丢失了虚拟方法。

我想过使用Linq,但问题是:

  • 我不知道如何从Linq表达式调用回调
  • Linq不对一个集合进行排序,它只能返回一个新集合

如何对通用Collection<T>进行排序?

6 个答案:

答案 0 :(得分:12)

如果你不需要在排序过程中调用虚拟覆盖,你应该可以这样做:

class SortableCollection<T> : Collection<T>
{
    private readonly List<T> _list;

    public SortableCollection() : this(new List<T>()) {}
    public SortableCollection(List<T> list) : base(list)
    {
        _list = list;
    }
    public void Sort() { _list.Sort(); }
}

或者这个:

class SortableCollection<T> : Collection<T>
{
    public SortableCollection() : this(new List<T>()) {}
    public SortableCollection(List<T> list) : base(list) {}
    public void Sort() { ((List<T>)Items).Sort(); }
}

答案 1 :(得分:1)

您可以使用SortedList<T>(也实现ICollection<T>,因此如果您愿意,可以将其视为集合。)

答案 2 :(得分:0)

如果您想要一个包含内容更改通知的可排序列表,请查看BindingList

答案 3 :(得分:0)

Collection<T>有一个索引器。如果您真的想要对项目进行排序,可以使用索引器实现您喜欢的任何排序算法。这是一个例子,通过适当的收集,可以采取O(N ^ 3)......

void SortInPlace(Collection<T> col)
{
    for(int i=0; i<col.Count - 1; i++)
        for(int j=i+1; j<col.Count; j++)
            if(col[i] < col[j]) // This won't compile, but you get the jist
                Swap col[i] and col[j]
}

如果您的集合仅提供O(N)项访问权限,则可以实施其中一种O(NlogN)算法以获得O(N ^ 2logN)排序性能。

答案 4 :(得分:0)

是的,你可以对一个集合进行排序试试这个:

public ICollection<T> getSortedData(ICollection<T> collection, string property, string direction)
{
    switch (direction.Trim())
    {
        case "asc":
            collection = ((from n in collection
                           orderby
                           n.GetType().GetProperty(property).GetValue(n, null)
                           select n).ToList<T>()) as ICollection<T>;
        break;
        case "desc":
            collection = ((from n in collection
                           orderby
                           n.GetType().GetProperty(property).GetValue(n, null)
                           descending
                           select n).ToList<T>()) as ICollection<T>;
        break;
    }
    return collection;
}

答案 5 :(得分:0)

使用ArrayList.Adapter(yourCollection)并将其排序为数组。