How to return a "chain" of OrderBy() calls for reusability
I have some LINQ-to-objects code as follows, which gets the items in a collection in a specific "complex" order:
var items = this.Items.OrderBy(a => a.DisplayType == DisplayType.Integer ? 0 : 1)
.ThenBy(a => a.DisplayType == isplayType.String ? 0 : 1)
.ThenBy(a => a.Name);
This works really well. However, I want to be able to reuse this "chain" without duplicating 开发者_运维百科the code.
I can do this fine while all of the types of the properties we're sorting on are the same:
private static Func<Column, int> GetOrderBy()
{
return a => a.DisplayType == FieldDisplayType.Integer ? 0 :
a.DisplayType == FieldDisplayType.String ? 1 : 2;
}
var items = this.Items.OrderBy(GetOrderBy());
but then I don't see how I can include a.Name - because the return type is Func, and Column.Name is a string.
Any help appreciated.
Tom
If you want to reuse that ordering, I would write an extension method which applies the ordering, instead of calling OrderBy:
internal static IOrderedEnumerable<Column> OrderByDefaults
(this IEnumerable<Column> source)
{
return source.OrderBy(a => a.DisplayType != FieldDisplayType.Integer)
.ThenBy(a => a.DisplayType != FieldDisplayType.String);
}
then call it with:
var items = this.Items.OrderByDefaults()
.ThenBy(a => a.Name);
Two points:
- I've not bothered with integers: "false" sorts less than "true", so I believe this does what you want. You can put it back to using integers for each property though
- The disadvantage of this approach is that you need to a static nongeneric top-level type for the extension method.
I would definitely stick to OrderBy/ThenBy/ThenBy instead of building your own big comparer with the conditional clause - simply because it's a lot easier to read, IMO.
精彩评论