Method Overloading. Can you overuse it?

2019-01-10 14:55发布

What's better practice when defining several methods that return the same shape of data with different filters? Explicit method names or overloaded methods?

For example. If I have some Products and I'm pulling from a database

explicit way:

public List<Product> GetProduct(int productId) {    // return a List    }
public List<Product> GetProductByCategory(Category category) {    // return a List    }
public List<Product> GetProductByName(string Name ) {    // return a List    }

overloaded way:

public List<Product> GetProducts() {    // return a List of all products    }
public List<Product> GetProducts(Category category) { // return a List by Category }
public List<Product> GetProducts(string searchString ) { // return a List by search string }

I realize you may get into a problem with similar signatures, but if you're passing objects instead of base types (string, int, char, DateTime, etc) this will be less of an issue. So... is it a good idea to overload a method to reduce the number of methods you have and for clarity, or should each method that filters the data a different way have a different method name?

16条回答
别忘想泡老子
2楼-- · 2019-01-10 15:00

As far as I can tell, you won't have fewer methods, just fewer names. I generally prefer the overloaded method system of naming, but I don't think it really makes much difference as long as you comment and document your code well (which you should do in either case).

查看更多
走好不送
3楼-- · 2019-01-10 15:00

You probably need some project-wide standards. Personally, I find the overloaded methods much easier to read. If you have the IDE support, go for it.

查看更多
该账号已被封号
4楼-- · 2019-01-10 15:00

The point of overloading to to ease the learning curve of someone using your code... and to allow you to use naming schemes that inform the user as to what the method does.

If you have ten different methods that all return a collection of employees, Then generating ten different names, (Especially if they start with different letters!) causes them to appear as multiple entries in your users' intellisense drop down, extending the length of the drop down, and hiding the distinction between the set of ten methods that all return an employee collection, and whatever other methods are in your class...

Think about what is already enforced by the .Net framework for, say constructors, and indexers... They are all forced to have the same name, and you can only create multiples by overloading them...

If you overload them, they will all appear as one, with their disparate signatures and comments off to tthe side.

You should not overload two methods if they perform different or unrelated functions...

As to the confusion that can exist when you want to overload two methods with the same signature by type as in

public List<Employee> GetEmployees(int supervisorId);
public List<Employee> GetEmployees(int departmentId); // Not Allowed !!

Well you can create separate types as wrappers for the offending core type to distinguish the signatures..

  public struct EmployeeId 
  { 
      private int empId;
      public int EmployeeId { get { return empId; } set { empId = value; } }
      public EmployeeId(int employeId) { empId = employeeId; }
  }

  public struct DepartmentId 
  {
   // analogous content
  }

 // Now it's fine, as the parameters are defined as distinct types...
 public List<Employee> GetEmployees(EmployeeId supervisorId);
 public List<Employee> GetEmployees(DepartmentId  departmentId);
查看更多
老娘就宠你
5楼-- · 2019-01-10 15:01

One thing you may consider is that you can't expose overloaded methods as operation contracts in a WCF Web Service. So if you think you may ever need to do this, it would be an argument for using different method names.

Another argument for different method names is that they may be more easily discoverable using intellisense.

But there are pros and cons for either choice - all design is trade-off.

查看更多
贼婆χ
6楼-- · 2019-01-10 15:01

A brief glance at the framework should convince you that numerous overloads is an accepted state of affairs. In the face of myriad overloads, the design of overloads for usability is directly addressed by section 5.1.1 of the Microsoft Framework Design Guidelines (Kwalina and Abrams, 2006). Here is a brief prècis of that section:

  • DO try to use descriptive parameter names to indicate the default used by shorter overloads.

  • AVOID arbitrarily varying parameter names in overloads.

  • AVOID being inconsistent in the ordering of parameters in overloaded members.

  • DO make only the longest overload virtual (if extensibility is required). Shorter overloads should simply call through to a longer overload.

  • DO NOT use ref or out parameters to overload members.

  • DO allow null to be passed for optional arguments.

  • DO use member overloading rather than defining members with default arguments.

查看更多
狗以群分
7楼-- · 2019-01-10 15:01

Another option is to use a Query object to build the "WHERE Clause". So you would have only one method like this:

public List<Product> GetProducts(Query query)

The Query object contains the condidition expressed in an Object Oriented way. The GetProducts obtain the query by "parsing" the Query object.

http://martinfowler.com/eaaCatalog/queryObject.html

查看更多
登录 后发表回答