Предположим, что я хочу иметь 2 функции, та, которая генерирует случайное целое число в данном диапазоне и то, которое генерирует случайное дважды в данном диапазоне.
int GetRandomNumber( int min, int max );
double GetRandomNumber( double min, double max );
Заметьте, что имена методов являются тем же. Я пытаюсь решить, назвать ли функции этим или...
int GetRandomInteger( int min, int max );
double GetRandomDouble( double min, double max );
Первая опция обладает преимуществом пользователя, не имеющего необходимость волноваться, по поводу которого они звонят. Они могут просто назвать GetRandomNumber с целыми числами или удваиваются, и получите результат.
Вторая опция является более явной на имена, но она показывает ненужную информацию вызывающей стороне.
Я знаю, что это мелко, но я забочусь о мелких вещах.
Править: Как C++ вел бы себя относительно неявного преобразования.
Пример:
GetRandomNumber( 1, 1 );
Это могло быть неявно преобразовано для функции GetRandomNumber для двойной версии. Очевидно, я не хочу, чтобы это произошло. C++ будет использовать международную версию перед двойной версией?
Я предпочитаю ваш второй пример, он явный и не оставляет двусмысленности в интерпретации. Лучше ошибиться в том, чтобы быть явным в именах методов, чтобы четко осветить цель и функцию этого члена.
Единственным недостатком вашего подхода является то, что вы связали имя метода с типом возвращаемого значения, что не идеально в случае, если вы хотите изменить тип возвращаемого значения одного из этих методов. Однако в таком случае мне лучше добавить новый метод и в любом случае не нарушать совместимость вашего API.
Я предпочитаю вторую версию. Мне нравится перегружать функцию, когда в конечном итоге две функции делают одно и то же; в этом случае они возвращают разные типы, поэтому это не совсем одно и то же. Другой вариант, если ваш язык поддерживает это, - определить его как общий / шаблонный метод, например:
T GetRandom<T>(T min, T max);
Имя функции должно указывать, что функция делает; Я не вижу смысла впихивать типы в имена. Так что определенно идите на перегрузку - вот для чего он нужен.
Я предпочитаю перегруженный метод. Посмотрите на метод Math.Min () в .NET. Он имеет 11 перегрузок: int, double, byte и т. Д.
Я обычно предпочитаю первый пример, потому что он не загрязняет пространство имен. Например, при его вызове, если я передаю целые числа, я ожидаю получить обратно целое число. Если я пас в парном разряде, я, вероятно, рассчитываю получить дубль. Компилятор выдаст ошибку, если вы напишете:
//this causes an error
double d = GetRandomNumber(1,10);
, так что это не большая проблема. и вы всегда можете привести аргументы, если вам нужно int, но у вас есть двойники для ввода ...
На некоторых языках вы не можете изменить тип возврата перегруженного функций для этого потребуется второй пример.
Предполагая, что C ++, второй также позволяет избежать проблем с двусмысленностью. Если вы сказали:
GetRandomNumber( 1, 5.0 );
какой из них следует использовать? Фактически, это ошибка компиляции.
Я думаю, что идеальным решением было бы
Int32.GetRandom(int min, int max)
Double.GetRandom(double min, double max)
, но, увы, статический метод расширения невозможен (пока?).
.net Framwork, похоже, предпочитает первый вариант ([ System.Math class ):
public static decimal Abs(decimal value)
public static int Abs(int value)
Как и Эндрю, я лично предпочел бы второй вариант, чтобы избежать двусмысленности, хотя я думаю, что это дело вкуса.