Достаточно ли, чтобы методы отличались только по имени аргумента (не по типу) или лучше назвать его более явно?
Так , например T Find<T>(int id)
против T FindById<T>(int id)
.
Есть ли веская причина называть его более явно (т.е. добавлять ById
) вместо сохранения только имени аргумента?
Я могу подумать об одной причине, когда сигнатуры методов одинаковы, но имеют разное значение.
FindByFirstName(string name)
а также FindByLastName(string name)
T Find<T>(string name)
или(int size)
как вы планируете решить неизбежные проблемы?ID
объектом, а не простоint
. Таким образом, получите проверку во время компиляции, что вы не используете id для int или наоборот в какой-то части вашего кода. И с этим вы можете иметьfind(int value)
иfind(ID id)
.Ответы:
Конечно, есть веская причина назвать это более явно.
Прежде всего, это не само определение метода , а само использование метода . И хотя
findById(string id)
иfind(string id)
оба говорят сами за себя, существует огромная разница междуfindById("BOB")
иfind("BOB")
. В первом случае вы знаете, что случайный литерал фактически является идентификатором. В последнем случае вы не уверены - на самом деле это может быть имя или что-то другое.источник
findById(id)
противfind(id)
. Вы можете пойти по любому пути.double Divide(int numerator, int denominator)
используется в методе:double murdersPerCapita = Divide(murderCount, citizenCount)
. Вы не можете полагаться на два метода, использующих одно и то же имя переменной, так как существует множество случаев, когда это не так (или когда это так, называете это плохо)Преимущества FindById () .
Будущее теплоизолирующие : Если начать с
Find(int)
, а затем должны добавить другие методы (FindByName(string)
,FindByLegacyId(int)
,FindByCustomerId(int)
,FindByOrderId(int)
, и т.д.), люди , как я , как правило , тратить возрастов ищутFindById(int)
. На самом деле не проблема, если вы можете и будете переходитьFind(int)
к тому времени,FindById(int)
когда это станет необходимым, - будьте готовы в будущем, если s.Легче читать .
Find
отлично подходит, если вызов выглядит,record = Find(customerId);
ноFindById
немного легче для чтения, если это такrecord = FindById(AFunction());
.Согласованность . Вы можете последовательно применять шаблон
FindByX(int)
/FindByY(int)
везде, ноFind(int X)
/Find(int Y)
это невозможно, поскольку они конфликтуют.Преимущества Find ()
Find
прост и понятен, и наряду сoperator[]
этим он является одним из 2 наиболее ожидаемых имен функций в этом контексте. (Некоторые популярные варианты тогоget
,lookup
илиfetch
, в зависимости от контекста).FindById(int id)
, мы можем легко удалить избыточность, изменив ее наFind(int id)
, но есть компромисс - мы теряем некоторую ясность.В качестве альтернативы вы можете получить преимущества обоих , используя строго типизированные идентификаторы:
Реализация
Id<>
: строго вводить значения идентификаторов в C #Комментарии здесь, а также в ссылке выше, вызвали многократные опасения относительно того,
Id<Customer>
что я хотел бы рассмотреть:CustomerId
иOrderID
это разные типы (customerId1 = customerId2;
=> хороший,customerId1 = orderId1;
=> плохой), но их реализация почти идентична, поэтому мы можем реализовать их либо с помощью вставки копии, либо с помощью метапрограммирования. В то время как в обсуждении есть смысл показывать или скрывать универсальное, метапрограммирование - то, для чего предназначены универсальные.DoSomething(int customerId, int orderId, int productId)
. Строго набранные идентификаторы также предотвращают другие проблемы, включая тот, о котором спрашивал ОП.int aVariable
. Легко сказать, что идентификатор удерживаетсяId<Customer> aVariable
, и мы можем даже сказать, что это идентификатор клиента.String
это просто обертка вокругbyte[]
. Упаковка или инкапсуляция не противоречат строгой типизации.operator==
иoperator!=
как хорошо, если вы не хотите , чтобы полагаться исключительно наEquals
:,
источник
Другой способ думать об этом - использовать безопасность типов языка.
Вы можете реализовать такой метод, как:
Где FirstName - это простой объект, который заключает в себе строку, которая содержит имя и означает, что не может быть путаницы ни в том, что делает метод, ни в аргументах, с которыми он вызывается.
источник
string name = "Smith"; findById(name);
Что возможно, если вы используете неописуемые общие типы.DWORD
LPCSTR
конце концов, я бы сказал, что большинство людей просто смотрят на бесконечные клоны и т. д. и думают, что «это int / string / etc.», и это приводит к тому, что вы тратите больше времени на поддержку своих инструментов, чем на разработку кода. ,int
s часто суммируются, умножаются и т. Д., Что не имеет смысла для идентификаторов; так что я быID
отличался отint
. Это может упростить API, сузив то, что мы можем сделать, учитывая значение (например, если у нас естьID
, он будет работать только сfind
, например,age
илиhighscore
). И наоборот, если мы много конвертируем или пишем одну и ту же функцию / метод (напримерfind
) для нескольких типов, это признак того, что наши различия слишком хорошиЯ буду голосовать за явное объявление, как FindByID .... Программное обеспечение должно быть построено для изменения. Он должен быть открытым и закрытым (ТВЕРДЫМ). Таким образом, класс открыт для добавления аналогичного метода поиска, например, скажем FindByName .. и т. Д.
Но FindByID закрыт, и его реализация проверена модулем.
Я не буду предлагать методы с предикатами, они хороши на общем уровне. Что делать, если на основе поля (ByID) у вас есть совершенно другая методология.
источник
Я удивлен, что никто не предложил использовать предикат, такой как следующее:
При таком подходе вы не только уменьшаете поверхность своего API, но и даете больше контроля пользователю, использующему его.
Если этого недостаточно, вы всегда можете расширить его для своих нужд.
источник