Что такое утиная печать?

Не проверял весь поток, поэтому он уже может быть здесь, но:

public static class FluentOrderingExtensions
    public class FluentOrderer<T> : IEnumerable<T>
    {
        internal List<Comparison<T>> Comparers = new List<Comparison<T>>();

        internal IEnumerable<T> Source;

        public FluentOrderer(IEnumerable<T> source)
        {
            Source = source;
        }

        #region Implementation of IEnumerable

        public IEnumerator<T> GetEnumerator()
        {
            var workingArray = Source.ToArray();
            Array.Sort(workingArray, IterativeComparison);

            foreach(var element in workingArray) yield return element;
        }

        private int IterativeComparison(T a, T b)
        {
            foreach (var comparer in Comparers)
            {
                var result = comparer(a,b);
                if(result != 0) return result;
            }
            return 0;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }

    public static FluentOrderer<T> OrderFluentlyBy<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate) 
        where TResult : IComparable<TResult>
    {
        var result = new FluentOrderer<T>(source);
        result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)));
        return result;
    }

    public static FluentOrderer<T> OrderFluentlyByDescending<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate) 
        where TResult : IComparable<TResult>
    {
        var result = new FluentOrderer<T>(source);
        result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)) * -1);
        return result;
    }

    public static FluentOrderer<T> ThenBy<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
        where TResult : IComparable<TResult>
    {
        source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)));
        return source;
    }

    public static FluentOrderer<T> ThenByDescending<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
        where TResult : IComparable<TResult>
    {
        source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)) * -1);
        return source;
    }
}

Использование:

var myFluentlyOrderedList = GetABunchOfComplexObjects()
    .OrderFluentlyBy(x=>x.PropertyA)
    .ThenByDescending(x=>x.PropertyB)
    .ThenBy(x=>x.SomeMethod())
    .ThenBy(x=>SomeOtherMethodAppliedTo(x))
    .ToList();

... при условии, конечно, что все предикаты возвращаемые типы, которые сопоставимы с самим собой. Он лучше работал бы со стабильной сортировкой, такой как MergeSort, а не со встроенной QuickSort .NET, но он предоставляет вам удобочитаемую возможность упорядочивания по нескольким полям, аналогичную SQL (во всяком случае, настолько близкую, насколько может достигнуть цепочка методов). Вы можете расширить это, чтобы приспособить элементы, которые не являются IComparable, определяя перегрузки, которые принимают лямбду сравнения вместо создания ее на основе предиката.

РЕДАКТИРОВАТЬ: Небольшое объяснение, поскольку комментатор получил некоторые плюсы: этот набор методов улучшает базовую функциональность OrderBy (), позволяя сортировать по множеству полей в порядке убывания важности. Реальным примером будет сортировка списка счетов по клиенту, а затем по номеру счета (или дате счета). Другие методы получения данных в этом порядке либо не будут работать (OrderBy () использует нестабильную сортировку, поэтому она не может быть объединена в цепочку), либо будут неэффективными и не будут выглядеть так, как вы пытаетесь.

388
задан Alan H. 4 June 2013 в 10:18
поделиться

1 ответ

Я пытаюсь понять известное изречение в своем пути: "Доза Python не заботится, что объект является реальной уткой или нет. Все, о чем это заботится, то, ли объект, первый 'шарлатан', второй 'как утка'".

существует хороший веб-сайт. http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14

автор указал, что утиный ввод позволил Вам создать свои собственные классы, которые имеют их собственную внутреннюю структуру данных - но получены доступ с помощью нормального синтаксиса Python.

-2
ответ дан 22 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: