views:

149

answers:

5

Hi.

I have a feeling this question is a can of worms but I am going to ask anyway... :)

I have a method:

private MembershipUser GetUserFromReader(SqlDataReader reader)

And I want overload this method with a different return type:

private User GetUserFromReader(SqlDataReader reader)

But the compiler complains that the two methods have the same signature.

So, what is the best way to do this? I would prefer to not add an unnecessary parameter just to change the method signature.

I have played with the idea of doing something like:

private User GetUserFromReader(T reader)

But haven't really explored this in full yet. It seems like I'll need to make a bunch of changes with how I use my reader object.

Any ideas? What is the best practice when you have two overloaded methods of the same signature?

Thanks for helping out...

+1  A: 

You can't change the return type on an overload. How is the compiler supposed to tell which one you want to use?

What you should do is return a common superclass of everything you might want to return, and then just return whatever is applicable.

Either that, or name the methods differently, since they clearly do different things.

Anon.
+2  A: 

Your only real options are:

  1. Change the name of the function
  2. Change the signature of the function

I hate to be trite, but there isn't a way around the restriction on differentiating methods solely by return type.

If one of the overloads is declared in a parent class then you can use the new keyword to "hide" the higher method from callers, but new (on a member declaration) is usually considered evil.

Adam Robinson
A: 

The simple answer is that, as far as C# is concerned, you can't. Overloading by return type is permitted (I think) by MSIL, but not by C#.

The only real choice (i.e, excluding adding a "dummy" parameter), is to call one method GetMembershipUserFromReader and the other GetUserFromReader

Rob
Correct; the CLR permits overloads to differ solely by return type. There are a number of subtle differences between C# rules for signature matching and CLR rules; this is the most obvious one.
Eric Lippert
@Eric: Do you know why this is implemented in the CLR? I thought this could be useful in some cases in C#, but my colleagues disagreed with me. But to me overloading the return type where it's not ambiguous makes sense. What do you think Eric?
Joan Venge
@Joan: In the MSIL language there is no such thing as "overload resolution". Every method (or virtual method slot) has a unique "token", and a method call is pretty much just "call the method associated with this token". Since there is no need to do overload resolution based on arguments, the return type can be part of the signature.
Eric Lippert
Thanks Eric, very informative.
Joan Venge
+6  A: 

Why overload it? Why not just let the method say what it does, like so:

private MembershipUser GetMembershipUserFromReader(SqlDataReader reader)
private User GetUserFromReader(SqlDataReader reader)
Luhmann
Thanks. I didn't really think about accessibility when I was asking the question. I think this is the best solution in this case because it is 'private'.
Code Sherpa
+5  A: 

If you really want to differentiate the return type, but use the same method signature, you could use generics:

private T GetUserFromReader<T>(SqlDataReader reader)

But it's much simpler to just rename the methods, as in Luhmann's answer.

Robert Harvey
Thanks a bundle. I'll give this a go when I run into the same situation with public methods. In this case, because it is private, I agree that Luhmann's answer is the best solution.
Code Sherpa