Mladen Prajdić Blog

Blog about stuff and things and stuff. Mostly about SQL server and .Net

Sorter - a kind of ISortable implementation

I often wondered why is there no ISortable interface of somekind in .Net.
I recently needed to sort items in the context menu in alphabetical order.
Sorting them was the begining of a journey which produced this class.
It sorts simple objects like int, string, etc... as well as complex objects
that have properties you wish to sort on.

EDIT: 2006-07-06

I've removed the code because I published version 2 of this class which is better and can be found here.

Legacy Comments


rockmoose
2006-06-28
re: Sorter - a kind of ISortable implementation
I think this is great work MLaden!
rockmoose

James Curran
2006-06-28
re: Sorter - a kind of ISortable implementation
The reason there is no ISortable inteface should be obvious : Who would implement it? Sorting places requirements on both the collection, and the object stored in the collection, hence instead of a ISortable interface, we'd need an ISortableObject & ISortableCollection.

But, what would be the distinction between ISortableObject & IComparable?

James Curran
2006-06-28
re: Sorter - a kind of ISortable implementation
As for technical improvements, you have the block:
TObject[] arr = new TObject[itemList.Count];
itemList.CopyTo(arr, 0);
_OriginalList = new List<TObject>(arr);
_OriginalList.Sort(CompareValues);

appearing three times in the code. Beside violating the first law of refactor (never copy'n'paste), the block itself isn't very good. You copy every item from the collection into an temp array, then copy each from the array to the internal list. You seem to be doing twice the work, just to use predefined methods. The whole thing can be reduced to:

public void SetNewCollection(IEnumerable newCollection)
{
_OriginalList = new List<TObject>();
foreach(TObject obj in newCollection)
_OriginalList.Add(obj);
_OriginalList.Sort(CompareValues);
}

Note that this works for both ILists and ICollections, so you can eliminate SetNewList(), and copy that method from the ctor. Further, you can use IEnumerator in the ctor signature, and eliminate half of you ctors.

The next problem is your CompareValues method. It does a lot of work, sometime which involves slow reflection, none of which is actually comparing the two values. Basically, on EVERY SINGLE comparison, you go through the same calculations to decide which comparison you are going to do, (and every time you come to the same decision). All that should be done once in the ctor, and delegate set to point to the decided on comparison. Then just use that delagate in the sort.

Mladen
2006-06-28
re: Sorter - a kind of ISortable implementation
Rocko: thanx!

James:
There would be no real distinction.
To me it's just more intuitive to type in ISortable than IComparable. But that's just me :)

Yes i already fixed refactoring, ctor and foreach issues a few hours after posting this in the class i work with.
Thanx for pointing it out though.
It was one of those "doh" moments when you do something, finish it and say "Now i'm done!" and BAM! an idea hits you in back of the head :)))

about CompareValues:
i was thinking exactly the same thing but i just felt too lazy to do it :)) will do it soon though.

Thanx for all the great tips and comments. Appriciated.

Next step i'm thinking about is sorting an object collection on multiple properties...

jezemine
2006-09-17
re: Sorter - a kind of ISortable implementation
I agree with James, IComparable is provided by the framework, it's all that you need to implement if you want a sortable collection.