C#: Sorting with anonymous function
Let's say I have a list of objects, and I want to sort it by the items DateModified property. Why can't I use a delegate like this? How should I sort these by D开发者_StackOverflowateModified if not as shown below:
public string SortByDateModified(List<CartItem> items)
{
items.Sort(new Func<CartItem, CartItem, bool>((itemA, itemB) =>
{
return itemA.DateModified < itemB.DateModified;
}));
}
Why not use a lambda expression?
public string SortByDateModified(List<CartItem> items)
{
items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified));
}
If you don't want to use lambdas or greater than .NET 2.0, use this:
public string SortByDateModified(List<CartItem> items)
{
items.Sort(delegate(CartItem itemA, CartItem itemB)
{
return itemA.DateModified.CompareTo(itemB.DateModified);
});
}
In my experience, in environments such as Unity, lambdas and even delegates can cause crashes or problems, especially on platforms like iOS. In that case you would want to make your sorter a separate function like so:
int SortCartItemFunction(CartItem itemA, CartItem itemB)
{
return itemA.DateModified.CompareTo(itemB.DateModified);
}
Then you could pass it to your sort call like this:
items.Sort(SortCartItemFunction);
The Sort
method takes a delegate called Comparison<T>
. You're trying to pass in a Func<int, int, bool>
, which is itself a delegate. There is no conversion between the delegate Func<int, int, bool>
and the delegate Comparison<T>
.
You can, however, use a lambda expression.
items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified));
Indeed, you use this very lambda expression and pass it into the Func<int, int, bool>
constructor*. However, there is no need. A lambda expression can be converted into any delegate whos signature matches - that is (a, b) => a.DateModified.CompareTo(b.DateModified)
can be assigned to something typed Func<int, int, int>
or something typed Comparison<T>
. In this case we pass it in to something which expects a Comparison<T>
.
*
With one minor adjustment. Sort expectes an integer as a return type. Negative values indicate less than, 0 indicates equal, and positive values indicate greater than.
bool
is not useful in such a delegate, usually int
is used because you need 3 values to represent the results of the comparison, less than, equal and greater than. .NET collections usually (if not always) assume -1 means less than, 0 means equal and 1 means greater than.
You would then, in your delegate, have to check if value x is less, equal or greater than value y. An interesting thing to note here is that if you flip the results, for example compare y with x instead you will sort in the opposite direction.
For the easiest way to sort the dates, check JohnC's answer, or Sam's.
精彩评论