Are there any best practices on returning different return types on overloaded methods? For instance if I have a Load method in my DAL, I either want to load a single item or a bunch of items. I know that I could use a number of approaches:
Load one object
MyBusinessObject LoadOne(int id)
{
}
Load multiple objects
MyBusinessObject[] LoadMany(params int[] ids)
{
}
Now something I know I can do is to overload one method and have different return types. Like so:
MyBusinessObject Load(int id)
{
}
And
MyBusinessObject[] Load(params int[] ids)
{
}
While it seems there's nothing to stop me doing this, and it keeps things tidy from an API perspective, does this seem like a good idea? I came across it last night and part of me thinks I shouldn't be doing this for the reason of wanting matching return types for overloaded method.
I could also have the Load(int id) method return a collection that only holds one item. It seems to me that this violates the principle of least surprise though in that if you're expecting one item returned, you should return that item, you shouldn't return a list containing a single item.
So here are my conflicting thoughts surrounding these ideas:
So the latter two thoughts kind of outweigh the first, but at the same time, the first thought seems like a programmatic best practice of sorts.
Are there any best practices surrounding this practice? I'd be interested to hear others' thoughts on the subject.
I might be tempted to make the API explicit and use plurality in the names:
Customer LoadCustomer(int id) {...}
Customer[] LoadCustomers(params int[] id) {...}
Actually, the params
is rarely useful here - you don't usually know the ids at compile-time.
You can just look to an existing APIs. Let's take LINQ for example, it has "Select" method that returns many entities and also "Single" method that returns only one entity. Most of the existing APIs has two different methods, not an overloaded ones and I think this is logical and more readable.
There are probably exceptions, but unless you have a really good reason to return different types, a function and its overloads should return the same type so that you don't drive other developers crazy.
For example:
var a = MyFunc("Some text");
and
var a = MyFunc(1);
both look like they should resolve the var to the same type to me. Before I deviated from having all overloads return the same type I would make sure I had a very solid reason for returning different types.
I tend to follow the first point in your list of "thoughts surronding this idea" that says "overloads should return the same type".
but you can then overload the "LoadMany" with some different scenarios;
public Customer Load(int id)
{
// return just one customer
}
public List<Customer> LoadMany()
{
// return every single customer
}
public List<Customer> LoadMany(int statusFilter)
{
// return a filtered list of customers
}
public List<Customer> LoadMany(DateTime InitialContactFrom)
{
// return a filtered list of customers
}
public List<Customer> LoadMany(DateTime InitialContactFrom, DateTime InitialContactBefore)
{
// return a filtered list of customers
}
...whatever combinations you need can obviously be added but in the end, LoadMany returns a list and Load returns one entity.
我个人的想法是,从API用户的角度来看,后一种方法似乎更容易理解。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.