Должны ли вы объявлять методы, используя перегрузки или необязательные параметры в C # 4.0? - PullRequest
90 голосов
/ 31 октября 2008

Я смотрел разговор Андерса о C # 4.0 и предварительный просмотр C # 5.0 , и это заставило меня задуматься о том, когда в C # доступны дополнительные параметры, что будет рекомендуемым способом объявления методов, которые не нужны все указанные параметры?

Например, что-то вроде FileStream класса имеет около пятнадцати различных конструкторов, которые можно разделить на логические «семейства», например. те, что ниже от строки, те, что из IntPtr, и те, что из SafeFileHandle.

FileStream(string,FileMode);
FileStream(string,FileMode,FileAccess);
FileStream(string,FileMode,FileAccess,FileShare);
FileStream(string,FileMode,FileAccess,FileShare,int);
FileStream(string,FileMode,FileAccess,FileShare,int,bool);

Мне кажется, что этот тип шаблона можно упростить, если вместо него использовать три конструктора и использовать необязательные параметры для параметров по умолчанию, что сделает различные семейства конструкторов более четкими [примечание: я знаю это изменение не будет сделано в BCL, я говорю гипотетически для такого типа ситуации].

Что вы думаете? Начиная с C # 4.0, будет ли разумнее делать тесно связанные группы конструкторов и методов единым методом с необязательными параметрами или есть веская причина придерживаться традиционного механизма многократной перегрузки?

Ответы [ 13 ]

0 голосов
/ 14 сентября 2016

Хотя они (предположительно?) Являются двумя концептуально эквивалентными способами, доступными вам для моделирования API с нуля, к сожалению, у них есть небольшая разница, когда вам нужно рассмотреть обратную совместимость во время выполнения для ваших старых клиентов. Мой коллега (спасибо Брент!) Указал мне на этот замечательный пост: проблемы с версиями с необязательными аргументами . Некоторая цитата из этого:

Причина, по которой необязательные параметры были введены в C # 4 в На первом месте была поддержка COM взаимодействия. Это оно. И теперь мы узнать о всех последствиях этого факта. Если у тебя есть метод с необязательными параметрами, вы никогда не можете добавить перегрузку с дополнительные необязательные параметры из-за боязни вызвать компиляцию переломный момент И вы никогда не сможете удалить существующую перегрузку, так как это всегда было изменением во время выполнения. Вы в значительной степени нуждаетесь относиться к нему как к интерфейсу. Ваш единственный выход в этом случае заключается в написать новый метод с новым именем. Так что знайте об этом, если вы планируете используйте необязательные аргументы в ваших API.

0 голосов
/ 10 июня 2015

Во многих случаях необязательные параметры используются для переключения исполнения. Например:

decimal GetPrice(string productName, decimal discountPercentage = 0)
{

    decimal basePrice = CalculateBasePrice(productName);

    if (discountPercentage > 0)
        return basePrice * (1 - discountPercentage / 100);
    else
        return basePrice;
}

Параметр Discount здесь используется для подачи оператора if-then-else. Существует полиморфизм, который не был распознан, а затем он был реализован как оператор if-then-else. В таких случаях гораздо лучше разделить два потока управления на два независимых метода:

decimal GetPrice(string productName)
{
    decimal basePrice = CalculateBasePrice(productName);
    return basePrice;
}

decimal GetPrice(string productName, decimal discountPercentage)
{

    if (discountPercentage <= 0)
        throw new ArgumentException();

    decimal basePrice = GetPrice(productName);

    decimal discountedPrice = basePrice * (1 - discountPercentage / 100);

    return discountedPrice;

}

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

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

Ситуация очень похожа на наличие параметров, которые могут быть нулевыми. Это в равной степени плохая идея, когда реализация сводится к таким утверждениям, как if (x == null).

Подробный анализ можно найти по следующим ссылкам: Избегание необязательных параметров и Избегание пустых параметров

0 голосов
/ 31 декабря 2012

Оба дополнительных параметра, перегрузка метода имеют свои преимущества или недостатки. Это зависит от вашего предпочтения выбирать между ними.

Необязательный параметр: доступно только в .Net 4.0. необязательный параметр уменьшить размер вашего кода. Вы не можете определить и ref параметр

перегруженные методы: Вы можете определить параметры Out и ref. Размер кода будет увеличиваться, но перегруженные методы легко понять.

...