Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there OrderBy and OrderByDescending but not OrderBy(SortOrder)?

Tags:

c#

.net

linq

api

Currently if we get direction of ordering as an external dependency we have to use if to apply this direction:

public static IEnumerable<FileInfo> getlist(string directory, string searchPattern, string order)
{
    var files = new DirectoryInfo(directory).EnumerateFiles(searchPattern);

    if (order == "A")
        return files.OrderBy(f => f.CreationTime);

    return files.OrderByDescending(f => f.CreationTime);
}

Why is there no overload of OrderBy that takes order direction as a parameter? In Reflector I see that it's more or less implemented internally but not exposed for some weird reason.

I would much rather prefer writing something like this:

public static IEnumerable<FileInfo> getlist(string directory, string searchPattern, string order)
{
    return new DirectoryInfo(directory)
        .EnumerateFiles(searchPattern)
        .OrderBy(f => f.CreationTime, order == "A" ? SortOrder.Ascending : SortOrder.Descending);
}

Update:

I can write this myself, just was hoping that it's already in the framework:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    ListSortDirection order)
{
    switch (order)
    {
        case ListSortDirection.Ascending: return source.OrderBy(keySelector);
        case ListSortDirection.Descending: return source.OrderByDescending(keySelector);
    }

    throw new ArgumentOutOfRangeException("order");
}
like image 671
Konstantin Spirin Avatar asked Dec 04 '22 12:12

Konstantin Spirin


1 Answers

Since a SortOrder enumeration can technically take on more than 2 values (think (SortOrder) 35) it wouldn't capture the duality exactly. Having 2 methods ensures there is no ambiguity or need for range-checking (which is missing from your example btw).

That said, here is the method you want:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    SortOrder order)
{
    if(order < SortOrder.Ascending || order > SortOrder.Descending)
    {
        throw new ArgumentOutOfRangeException("order");
    }

    return order == SortOrder.Ascending
        ? source.OrderBy(keySelector)
        : source.OrderByDescending(keySelector);
}
like image 178
Bryan Watts Avatar answered Dec 25 '22 19:12

Bryan Watts