Почему методы, которые принимают неограниченное количество параметров, часто определяют перегрузки с меньшим количеством параметров?

36

Например, System.IO.Path.Combineметод в .NET имеет следующие перегрузки:

Combine(params String[])
Combine(String, String)
Combine(String, String, String)
Combine(String, String, String, String)

Какой смысл последних трех?

Первый будет охватывать их все, как будто вы смотрите внимательно, он использует paramsключевое слово. Аргумент обратной совместимости будет охватывать только Combine(String, String)вариант, так как это была единственная версия до .NET 4.

Alex
источник

Ответы:

56

Основная причина в производительности. Синтаксический сахар "неограниченные аргументы" на самом деле представляет собой массив строк. Если вы передаете только одну строку, зачем создавать массив только с одной строкой? Особенно, если ~ 90% вызовов этого метода будут с 3 или менее аргументами, нет необходимости в объекте массива с более тяжелым весом. Это немного легче в памяти и занимает немного меньше времени на обработку, потому что вам не нужен цикл для определения метода. Если у вас есть три строки, вы просто код для трех строк.

Грег Бургхардт
источник
Еще одна вещь, которую стоит отметить, это то, что проход Combineс нулевым или одним сегментом пути даже не имеет смысла, но paramsверсия позволяет вам это делать.
Матфея
4
Причина того, что число перегрузок, принимающих разные количества аргументов, не в удобочитаемости. Это связано с производительностью из-за накладных расходов, возникающих при создании массива строк и последующей их обработке. Причиной принятия params string[]является удобочитаемость.
Грег Бургхардт
2
Производительность действительно является причиной, и я полагаю, что это именно для случая, когда функция должна вызываться из внутренних циклов . Как написано в аннотации Брэда Абрамса на стр.27 языка программирования C #, в третьем издании сказано: «[C] Модель C # действительно создает дополнительное выделение объектов (содержащий массив) неявно при каждом вызове. Это редко проблема, но во внутренней - в сценариях типа «петля», где это может стать неэффективным, мы предлагаем обеспечить перегрузки для основных случаев и использовать paramsперегрузку только для крайних случаев. Примером является StringBuilder.AppendFormat()семейство перегрузок ».
Элия ​​Каган
3
@LowFlyingPelican Mono и .NET Framework - это не одно и то же. Если вы посмотрите на версию .NET Framework , это на самом деле совсем другое решение.
Алекс
3
@LowFlyingPelican: причина .NET Framework - производительность. Причиной реализации этого метода Моно была совместимость API с .NET. Причиной реализации этого метода в Mono была простота реализации (из-за того, что у них было значительно меньше ресурсов, чем у Microsoft).
jhominal
4

Синтаксический сахар.

При манипулировании путями к файлам очень распространено иметь небольшое количество фиксированных значений. В этих случаях удобнее использовать их напрямую, чем упаковывать их в массив.

Горт Робот
источник
3
С помощью params вы уже выпили это. msdn.microsoft.com/en-us/library/w5zay9db.aspx Нет необходимости в массиве.
Томас Джанк
3
В C # у вас есть точка, @Thomas. Однако .NET также поддерживает другие языки без params.
Карл Билефельдт
@ThomasJunk Эта ссылка для меня, к сожалению, мертва, но я уверен, что вы правы, так как мой C # посредственный. Я только что видел много библиотек со многими языками, которые делают это, чтобы позволить чистый код.
Gort the Robot