Да, перегрузка может быть легко использована.
Я обнаружил, что ключом к определению того, оправдана ли перегрузка или нет, является учет аудитории - не компилятора, а программиста по обслуживанию, который придет через несколько недель / месяцев / лет и должен понять, что код пытается достичь.
Простое имя метода, такое как GetProducts (), является ясным и понятным, но в нем много чего не сказано.
Во многих случаях, если параметр, переданный в GetProducts (), имеет правильное имя, специалист по техническому обслуживанию сможет определить, что делает перегрузка, но это зависит от хорошей дисциплины именования в момент использования, что вы можете ' исполнять. То, что вы можете применить - это имя метода, который они вызывают.
Принцип, которому я следую, состоит в том, чтобы перегружать методы, только если они взаимозаменяемы - если они делают то же самое. Таким образом, я не против, какую версию вызывает потребитель моего класса, поскольку они эквивалентны.
Чтобы проиллюстрировать это, я бы с радостью использовал перегрузки для метода DeleteFile ():
void DeleteFile(string filePath);
void DeleteFile(FileInfo file);
void DeleteFile(DirectoryInfo directory, string fileName);
Однако для ваших примеров я бы использовал отдельные имена:
public IList<Product> GetProductById(int productId) {...}
public IList<Product> GetProductByCategory(Category category) {...}
public IList<Product> GetProductByName(string Name ) {...}
Наличие полных имен делает код более понятным для специалиста по техобслуживанию (который вполне может быть мной). Это позволяет избежать проблем, связанных с конфликтами подписей:
// No collisions, even though both methods take int parameters
public IList<Employee> GetEmployeesBySupervisor(int supervisorId);
public IList<Employee> GetEmployeesByDepartment(int departmentId);
Существует также возможность введения перегрузки для каждой цели:
// Examples for GetEmployees
public IList<Employee> GetEmployeesBySupervisor(int supervisorId);
public IList<Employee> GetEmployeesBySupervisor(Supervisor supervisor);
public IList<Employee> GetEmployeesBySupervisor(Person supervisor);
public IList<Employee> GetEmployeesByDepartment(int departmentId);
public IList<Employee> GetEmployeesByDepartment(Department department);
// Examples for GetProduct
public IList<Product> GetProductById(int productId) {...}
public IList<Product> GetProductById(params int[] productId) {...}
public IList<Product> GetProductByCategory(Category category) {...}
public IList<Product> GetProductByCategory(IEnumerable<Category> category) {...}
public IList<Product> GetProductByCategory(params Category[] category) {...}
Код читается намного больше, чем написано - даже если вы никогда не вернетесь к коду после первоначальной проверки в системе контроля версий, вы все равно будете читать эту строку кода пару десятков раз, пока Вы пишете следующий код.
Наконец, если вы не пишете одноразовый код, вам нужно разрешить другим людям звонить вашему коду с других языков. Похоже, что большинство бизнес-систем в конечном итоге остаются на производстве намного дольше, чем их использование на сегодняшний день. Может случиться так, что код, который потребляет ваш класс в 2016 году, в конечном итоге будет написан на VB.NET, C # 6.0, F # или что-то совершенно новое, еще не изобретенное. Возможно, язык не поддерживает перегрузки.