Extension for choosing an extension for use in Linq

Can I choose which function to use in Linq?
An example of what I now have:

List<int> list = new List<int>(); bool bDescend = false; var listOrdered = bDescend ? list.OrderByDescending(it => it) : list.OrderBy(it => it); 

You see that I choose which function to use depending on the value of bDescend - so there are actually two Linq queries, not one.
Is it possible to avoid this by setting a condition inside a single query? Maybe something like

 list.ChooseFunction(bDescend ? OrderBy : OrderByDescending)... 

The actual code is more satisfied, and if such a trick is possible, it will make the code more readable.
Metaprogramming seems to be ...

+4
source share
3 answers

You can create your own extension method:

 enum Ordering { Ascending, Descending, } // trivial to convert to use booleans instead // of an enum if that 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); } } 

And then call it like

 var order = Ordering.Descending; .... MyList.OrderBy(order, it => it); 

It’s also possible to create an element of type ChooseFunction , but it should look like ChooseFunction(bdescend ? "OrderBy" : "OrderByDescending") , and I don’t even want to understand how ugly those magic lines that refer to function names are ugly. You will also have to either hardcode the SelectFunction extension or rely on reflection, which is ridiculously expensive for the simple thing you're trying to do

+4
source

You can create 2 Comparers: upstream and downstream, then pass one of them to the OrderBy method, i.e.:

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

If you don't mind losing the syntax of the extension method, you can use the delegate to specify the sort method:

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

Source: https://habr.com/ru/post/1443352/


All Articles