是否可以选择在Linq中应用哪个功能?
我现在拥有的例子:
List<int> list = new List<int>();
bool bDescend = false;
var listOrdered = bDescend ? list.OrderByDescending(it => it) :
list.OrderBy(it => it);
您看到我根据bDescend值选择要应用的功能 - 因此实际上有两个Linq查询,而不是一个。
是否可以通过在一个查询中放置条件来避免它?
也许像是
list.ChooseFunction(bDescend ? OrderBy : OrderByDescending)...
真正的代码更加恭维,如果这样的技巧可能会使代码更具可读性。
看起来像是一种元编程......
答案 0 :(得分:4)
您可以创建自己的扩展方法:
enum Ordering
{
Ascending,
Descending,
}
// trivial to convert to use booleans instead
// of an enum if that's truly what you need
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source, Ordering ordering, Func<TSource, TKey> keySelector)
{
if (ordering == Ordering.Ascending)
{
return source.OrderBy(keySelector);
}
else
{
return source.OrderByDescending(keySelector);
}
}
然后将其称为
var order = Ordering.Descending;
....
MyList.OrderBy(order, it => it);
除此之外,它可以制作一个ChooseFunction
类型的东西,但它必须看起来像ChooseFunction(bdescend ? "OrderBy" : "OrderByDescending")
而我甚至不想进入这些神奇的字符串指的是多么丑陋功能名称是。您还必须对ChooseFunction扩展程序进行硬编码,或依赖于反射,这对于您正在尝试的简单操作来说是非常昂贵的
答案 1 :(得分:2)
您可以创建2个比较器:升序和降序,然后将其中一个传递给OrderBy
方法,即:
list.OrderBy(it => it, asc ? new AscComparer() : new DescComparer())
答案 2 :(得分:0)
如果您不介意丢失扩展方法语法,可以使用委托来指定排序方法:
List<int> list = new List<int>();
Func<IEnumerable<int>, Func<int, int>,IEnumerable<int>> sorter;
if (cond)
{
sorter = Enumerable.OrderBy<int, int>;
}
else
{
sorter = Enumerable.OrderByDescending<int, int>;
}
var sorted = sorter(list, _ => _);