18.12.2017 Real Life ComparerBuilder
 
Залил в github свой старый сабж

Кроме отсутствия Emit есть ещё две вишенки на торте:
1. Опция "Null идут раньше/позже не-наллов?"
2. больше кастомизации. В примере ниже впереди идут доктора, причем сначала 42-летние, потом все остальные отсортированные по имени, тайтлу и возрасту.

Пример
public class Demo
{
    class Person
    {
        public string Title;
        public string Name;
        public int? Age;
    }

    public static void Test()
    {
        StringComparer ignoreCase = StringComparer.InvariantCultureIgnoreCase;
        string highlightTitle = "Dr.";
        int highlightAge = 42;

        IComparer<Person> comparer = new ComparerBuilder<Person>()
            .Compare(x => ignoreCase.Equals(highlightTitle, x.Title))
            .Compare(x => x.Age.HasValue && highlightAge == x.Age.Value)
            .CompareString(x => x.Name, ignoreCase)
            .CompareString(x => x.Title, ignoreCase)
            .Compare(x => x.Age, OrderFlavour.Backward | OrderFlavour.NullGoesFinally)
            .GetComparer();

        Enumerable.Empty<Person>().ToList().Sort(comparer);
        Enumerable.Empty<Person>().OrderBy(x => x, comparer).ToList();
    }
}


Сам ComparerBuilder.cs (около 100 строчек кода)
Понятно что если сортировать ValueTypes то будут короткоживущие боксинги. Другие косяки есть?


P.S. Кстати, а почему в Enumerable нет
IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, IComparer<TSource> comparer)