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.
Return type does not matter while overloading a method. We just need to ensure there is no ambiguity! The only way Java can know which method to call is by differentiating the types of the argument list.
The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and different return types. It will throw a compile-time error. If both methods have the same parameter types, but different return types, then it is not possible.
In java, method overloading can't be performed by changing return type of the method only. Return type can be same or different in method overloading. But you must have to change the parameter. Return type must be same or covariant in method overriding.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With