简体   繁体   中英

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 DateModified 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM