2012-11-01 37 views
4

是否可以選擇在Linq中應用哪個功能?什麼我現在有
例子:分機選擇在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)... 

真正的代碼更加compliated,如果這樣的伎倆可能會使得代碼更易讀。
看起來像那種元編程..

回答

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擴展程序進行硬編碼,或者依靠反射,這對於您嘗試執行的簡單操作來說是非常昂貴的。

+0

我把它編輯的自由是工作和更通用。 :)如果你願意,隨時回滾。 –

+0

@JeffMercado謝謝!如果我可以+1編輯,我會:) – Earlz

2

您可以創建2個比較器:升序和降序,然後傳遞其中一個到OrderBy方法,即:

list.OrderBy(it => it, asc ? new AscComparer() : new DescComparer()) 
+0

我同意這是要走的路。創建和擴展方法會降低可靠性。只是內聯。 – andleer

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, _ => _);