Почему не С# Math.Min/Max variadic?
Мне нужно найти минимум между 3 значениями, и я закончил делать что-то вроде этого:
Math.Min(Math.Min(val1, val2), val3)
Мне кажется, что это немного глупо, потому что для других языков используются вариационные функции. Я очень сомневаюсь, что это был надзор, хотя.
Есть ли какая-то причина, почему простая функция Min/Max не была изменчивой? Имеются ли последствия для производительности? Есть ли вариационная версия, которую я не заметил?
Ответы
Ответ 1
Если это набор (подкласс IEnumerable<T>
), можно легко использовать функции в библиотеке System.Linq
int min = new int[] {2,3,4,8}.Min();
Кроме того, легко реализовать эти методы самостоятельно:
public static class Maths {
public static T Min<T> (params T[] vals) {
return vals.Min();
}
public static T Max<T> (params T[] vals) {
return vals.Max();
}
}
Вы можете вызвать эти методы только с помощью простых скаляров, поэтому Maths.Min(14,25,13,2)
даст 2
.
Это общие методы, поэтому нет необходимости реализовывать этот метод для каждого типа чисел (int
, float
,...)
Я думаю, что основная причина, по которой эти методы не реализованы вообще, заключается в том, что каждый раз, когда вы вызываете этот метод, должен быть создан массив (или, по крайней мере, объект IList
). Сохраняя методы низкого уровня, можно избежать накладных расходов. Однако я согласен, что можно добавить эти методы в класс Math
, чтобы облегчить жизнь некоторым программистам.
Ответ 2
CommuSoft обратился к тому, как выполнить эквивалент в С#, поэтому я не буду исправлять эту часть.
Чтобы конкретно рассмотреть ваш вопрос "Почему не С# Math.Min/Max variadic?", приходят на ум две мысли.
Во-первых, Math.Min(и Math.Max) на самом деле не является языковой функцией С#, это функция .NET framework library. Это может показаться педантичным, но это важное различие. На самом деле, С# не предоставляет какую-либо особенность специального языка для определения минимального или максимального значения между двумя (или более) потенциальными значениями.
Во-вторых, как неоднократно указывал Эрик Липперт, языковые функции (и, предположительно, структурные функции) не "удаляются" или активно исключаются - все функции не реализованы до тех пор, пока кто-то не разработает, не реализует, не тестирует, не документирует и не передает эту функцию, См. здесь пример.
Не будучи разработчиком платформы .NET, я не могу говорить о фактическом процессе принятия решения, но это похоже на классический случай функции, которая просто никогда не поднималась до уровня включения, подобно последовательности foreach "особенность" Эрик обсуждает в предоставленной ссылке.
Ответ 3
Я думаю, что CommuSoft предоставляет надежный ответ, который, по крайней мере, подходит для людей, которые ищут что-то в этом направлении, и это должно быть принято.
С учетом сказанного, причина заключается в том, чтобы избежать накладных расходов, необходимых для менее вероятного варианта использования, когда люди хотят сравнить группу, а не два значения.
Как указано в @arx, использование параметрической системы было бы лишними накладными расходами для наиболее часто используемого случая, но также было бы слишком много лишних накладных расходов в отношении цикла, который должен был бы использоваться внутри, чтобы пройти через массив n - 1 раз.
Я могу легко увидеть аргумент для создания метода в дополнение к основной форме, но с LINQ, который больше не нужен.