4

是否可以选择在 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)...

真正的代码更复杂,如果这种技巧可能的话,它会使代码更具可读性。
看起来像一种元编程..

4

3 回答 3

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 扩展进行硬编码,或者依赖反射,这对于您尝试做的简单事情来说非常昂贵

于 2012-11-01T02:03:46.510 回答
2

您可以创建 2 个比较器:升序和降序,然后将其中一个传递给OrderBy方法,即:

list.OrderBy(it => it, asc ? new AscComparer() : new DescComparer())
于 2012-11-01T02:12:30.720 回答
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, _ => _);
于 2012-11-05T20:01:49.977 回答