Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use different return types on overloaded methods?

Tags:

c#

.net

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:

  • Overloaded methods should all return the same type.
  • If methods do the same thing, don't give them a bunch of different names, overload the same method name. It makes things simpler from an API user's perspective, they don't have to trawl through a bunch of different methods that all essentially do the same thing but with different parameters.
  • Return the most obvious type for the method, i.e. if the user is likely to be expecting a collection of items, return a collection of items, if they are likely to be expecting a single item, return a single item.

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.

like image 213
BenAlabaster Avatar asked Oct 11 '09 19:10

BenAlabaster


People also ask

Does return type matter in overloading?

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.

Why method overloading have different return types?

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.

Should return type be same in method overloading and overriding?

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.


4 Answers

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.

like image 185
Marc Gravell Avatar answered Oct 06 '22 05:10

Marc Gravell


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.

like image 28
Restuta Avatar answered Oct 06 '22 05:10

Restuta


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.

like image 30
overstood Avatar answered Oct 06 '22 07:10

overstood


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.

like image 41
Stuart Helwig Avatar answered Oct 06 '22 06:10

Stuart Helwig