Нахождение значений надежная и возвращая Кортеж, в результате


Я был кодирования некоторые инструментальные вещи, когда я начал размышлять, может ли лучший тип возвращаемого значения для метода диапазоне / Минмакс применяться на метод интерфейса IEnumerable.

Я использую значение в C# 7 ОК, как показано ниже, но соблазн создать свой класс с полями только для чтения.

    public static (TSource Min, TSource Max) MinMax<TSource>(this IEnumerable<TSource> source, IComparer<TSource> comparer)
    {
        using (var sourceIterator = source.GetEnumerator())
        {
            if (!sourceIterator.MoveNext())
            {
                throw new InvalidOperationException("Sequence contains no elements");
            }

            var max = sourceIterator.Current;
            var min = sourceIterator.Current;

            while (sourceIterator.MoveNext())
            {
                var candidate = sourceIterator.Current;

                if (comparer.LeftStrictlyLesserThanRight(candidate, min))
                {
                    min = candidate;
                }

                if (comparer.LeftStrictlyGreaterThanRight(candidate, max))
                {
                    max = candidate;
                }
            }

            return (min, max);
        }
    }

Коммунальные услуги определены как ниже:

internal static class ComparerExtensions
{
    public static bool LeftStrictlyGreaterThanRight<T>(this IComparer<T> comparer, T left, T right)
    {
        return comparer.Compare(left, right) > 0;
    }
    public static bool LeftStrictlyLesserThanRight<T>(this IComparer<T> comparer, T left, T right)
    {
        return comparer.Compare(left, right) < 0;
    }
}

Что вы считаете лучшим, зная, что создаете ссылку типа принесет некоторые дополнительные ассигнования и работы ГК (я имею в виду, что был весь смысл, чтобы иметь структуру, как кортежи в C# 7). Что меня беспокоит в кортеже, что поля не только для чтения, и мы не можем предотвратить пользователей способ испортить и сломать поток.

Я не знаю, может это только у меня и моего сверх-оборонительный стиль кодирования и неудачный опыт использования Python, где шифровальщики считаются "взрослыми"?



291
5
задан 14 апреля 2018 в 09:04 Источник Поделиться
Комментарии
2 ответа


Что меня беспокоит в кортеже, что поля не только для чтения, и мы не можем предотвратить пользователей способ испортить и сломать поток.

Мы не можем предотвратить все, и иногда это просто легче и быстрее использовать самое простое решение, как кортежи в этом случае. Вы можете всегда переключиться на что-то более сложное, если это необходимо, но это хорошо, чтобы начать, следуя принципу YAGNI.



Я был кодирования некоторые инструментальные вещи

Он depnds на какие инструментальные вещи вашего кода. Если это какой-то крошечный помощник тогда я пойду с кортежами. Если бы я был creatng общего назначения библиотеки и большой типа будет лучше. Можно проверить параметры и убедиться, что min <= max и т. д.

В качестве примера вы можете взглянуть на мои родовые Range.cs что поддерживается выражений уметь работать с любой сравнимый тип BinaryOperation.cs.


Относительно вашего ComparerExtensions Я начну с того, что я уже сказал в мой комментарий: LeftStrictlyLesserThanRight - Я думаю, что практически все языки программирования называют это просто "меньше" и его аналог меньше-чем-или-равно.

Я также найти расширения не интуитивно. Они должны быть расширения на T и не на компаратор так:

x.LessThen(y)

и/или

x.LessThen(y, comparer)

Это более естественно (и короче) написать, чем


comparer.LeftLessThenRight(x, y)


Это означает, что вы можете создать две пары из этих расширений для каждой операции.

public static bool LessThen<T>(this T x, T y) where T : IComparable<T>
public static bool LessThen<T>(this T x, T y, IComparer<T> comparer)

тот, который использует интерфейс IComparable реализован T а другой, который использует пользовательский компаратора.

4
ответ дан 15 апреля 2018 в 10:04 Источник Поделиться

Можете использовать else if на втором

Мне не нравится имя LeftStrictlyLesserThanRight но вы могли бы просто использовать, что и на флопе candidate, max для LeftStrictlyLesserThanRight.

1
ответ дан 14 апреля 2018 в 11:04 Источник Поделиться