While everyone's answers will work, they weren't exactly where I was trying to get with this. Originally, I had a method of the class called Sort:
public void Sort<TKey>( Func<T, TKey> keySelector, . . . ) {
// . . .
}
This worked well, but then I found a bug in my UI that was related to calling the Sort method more than once. The sort itself worked, that wasn't the problem. The bug is convoluted and difficult to explain, and I'd rather not go into it. But the easiest solution was to make sure that the collection was sorted only once, on the correct key. The thing is that the keys differed depending on the particular drop down that the collection was bound to. So I needed a way to encapsulate the sort criteria in the collection so it would do the proper sort the first and only time.
As I already had the Sort
method mentioned above, I figured the easiest thing to do was to put the keySelector parameter to it into a property of the class. It turns out that the language doesn't let you do that, and now I know and understand why.
What I ended up doing to get this to work was replace the Func
property with a reference to an object that implements IComparer<T>
. I have no trouble declaring this property and it's easy to declare a class that implements it for each type passed as the T
parameter in a collection declaration. I just initialize the property after allocating the collection object and I rewrote the Sort
method so it looks like this:
public void Sort() {
if ( Comparer != null ) {
InternalSort( Items.Skip( RowsToSkip ).OrderBy( item => item, Comparer ) );
} else {
InternalSort( Items.Skip( RowsToSkip ).OrderBy( item => item ) );
}
}
RowsToSkip
is an int
property of the class which specifies how many rows at the start of the collection are to be skipped. This lets me add an entry like "Pick a choice" at the start of the list and not have the sort move it.