Reputation: 256741
I have a generic collection:
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();
...
}
Now I need a way to sort this collection in-place.
I tried converting my class to use List<T>
rather than Collection<T>
(since Collection<T>
doesn't support the concept of an order). That then allowed calling the Sort
method:
this.Items.Sort(SortCompareCallback);
protected virtual int SortCompareCallback(Object x, Object y)
{
return OnCompareItems(new SortCompareEventArgs(x, y, this.sortColumnIndex, direction));
}
But then I lose the virtual methods when the list is modified.
I thought about using Linq, but the problem with that is:
How can I sort a generic Collection<T>
?
Upvotes: 16
Views: 40533
Reputation: 43046
If you don't need to have the virtual overrides called during the sorting, you should be able to do something like this:
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(); }
}
Or this:
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(); }
}
Upvotes: 13
Reputation: 1
Use ArrayList.Adapter(yourCollection)
and sort it as an array.
Upvotes: 0
Reputation: 89
Yes you can sort a collection try this:
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;
}
Upvotes: 1
Reputation: 39013
Collection<T>
has an indexer. If you really want to sort the items in place, you can implement whatever sorting algorithm you prefer using the indexer. Here's an example that, with the proper Collection, can take 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]
}
You can implement one of the O(NlogN) algorithms to get an O(N^2logN) sort performance if your collection only offers O(N) item access.
Upvotes: 2
Reputation: 51339
If you want a sortable list with content change notification, you should look at BindingList
Upvotes: 0
Reputation: 150108
You can use SortedList<T>
(which also implements ICollection<T>
, so you can treat it like a collection if you want to).
Upvotes: 1