在定义使用不同过滤器返回相同形状数据的多个方法时,有什么更好的做法?显式方法名称或重载方法?
例如.如果我有一些产品,我从数据库中提取
明确的方式:
public ListGetProduct(int productId) { // return a List } public List GetProductByCategory(Category category) { // return a List } public List GetProductByName(string Name ) { // return a List }
重载方式:
public ListGetProducts() { // return a List of all products } public List GetProducts(Category category) { // return a List by Category } public List GetProducts(string searchString ) { // return a List by search string }
我意识到你可能会遇到类似签名的问题,但是如果你传递的是对象而不是基类型(string,int,char,DateTime等),这将不再是一个问题.所以...是一个好主意,重载的方法来减少你有方法和清晰的数字,或者应该每种方法是对数据进行过滤以不同的方式有不同的方法名?
是的,重载很容易被滥用.
我发现确定过载是否合理的关键是考虑受众 - 而不是编译器,而是维护程序员将在几周/几个月/几年内出现,并且必须了解代码是什么试图实现.
一个简单的方法名称,如GetProducts()是清晰易懂的,但它确实留下了很多未说明的内容.
在许多情况下,如果传递给GetProducts()的参数命名良好,维护人员将能够计算出重载的作用 - 但这依赖于在使用点的良好命名规则,而您无法强制执行.您可以强制执行的是他们调用的方法的名称.
我遵循的指导原则是只有在可以互换的情况下才重载方法 - 如果他们做同样的事情.这样,我不介意我班级的消费者调用哪个版本,因为它们是等价的.
为了说明,我很乐意为DeleteFile()方法使用重载:
void DeleteFile(string filePath); void DeleteFile(FileInfo file); void DeleteFile(DirectoryInfo directory, string fileName);
但是,对于您的示例,我将使用单独的名称:
public IListGetProductById(int productId) {...} public IList GetProductByCategory(Category category) {...} public IList GetProductByName(string Name ) {...}
拥有全名使得代码对于维护人员(可能是我)更明确.它避免了签名冲突的问题:
// No collisions, even though both methods take int parameters public IListGetEmployeesBySupervisor(int supervisorId); public IList GetEmployeesByDepartment(int departmentId);
还有机会为每个目的引入重载:
// Examples for GetEmployees public IListGetEmployeesBySupervisor(int supervisorId); public IList GetEmployeesBySupervisor(Supervisor supervisor); public IList GetEmployeesBySupervisor(Person supervisor); public IList GetEmployeesByDepartment(int departmentId); public IList GetEmployeesByDepartment(Department department); // Examples for GetProduct public IList GetProductById(int productId) {...} public IList GetProductById(params int[] productId) {...} public IList GetProductByCategory(Category category) {...} public IList GetProductByCategory(IEnumerable category) {...} public IList GetProductByCategory(params Category[] category) {...}
代码读取的次数比写入的要多得多 - 即使您在初始检查源代码控制后再也没有回到代码中,在编写代码时,您仍然会读取该行代码几十次.随后的代码.
最后,除非您正在编写一次性代码,否则您需要允许其他人使用其他语言调用您的代码.似乎大多数业务系统最终都会在日期之前保持生产状态.可能是2016年消耗你的类的代码最终是用VB.NET,C#6.0,F#或者尚未发明的全新内容编写的.可能是该语言不支持重载.
据我所知,你不会有更少的方法,只有更少的名字.我通常更喜欢重载的命名方法系统,但我认为只要你很好地评论和记录你的代码(在任何一种情况下都应该这样做),它并没有太大的区别.
你能过度使用它吗?嗯,是的,这是真的.
但是,您给出的示例是何时使用方法重载的完美示例.它们都执行相同的功能,为什么只是因为你将不同的类型传递给它们而给它们不同的名称.
主要规则是做最清楚,最容易理解的事情.不要使用重载只是为了光滑或聪明,在有意义的时候去做.其他开发人员也可能正在处理此代码.您希望让它们尽可能简单地获取并理解代码,并能够在不实现错误的情况下实现更改.
我喜欢重载我的方法,以便以后在intellisense中我没有相同的方法.对我来说,让它过载而不是让它的命名方式不同十几次似乎更合乎逻辑.
您可以考虑的一件事是您不能将重载的方法公开为WCF Web服务中的操作契约.因此,如果您认为您可能需要这样做,那么使用不同的方法名称将是一个争论.
不同方法名称的另一个论点是使用intellisense可以更容易地发现它们.
但两种选择都有利弊 - 所有设计都是权衡取舍.