views:

264

answers:

6

Hy, i know it sounds a very stupid question.
Here's what i found:

public static List<SomeDTO> GetData(Guid userId, int languageId)
 {
 // Do something here
 }

    public static List<int> GetData(Guid userId ,int iNumberOfItems)
    {
      var result = GetData(userID,0);

     return  (from r in result select c.id).Take(iNumberOfItems).ToList<int>();
    }

I get a compilation error:

ClassLibrary' already defines a member called 'GetData' with the same parameter types

The second only returning the ids of the first function.

I know this isn't working.
I know there's both returning a List<> type ,but they returning differentypes.
Could somebody explain me why?
How can i solve this?

Update This problem is solved on F# !

+4  A: 

The return type of a method is not part of the signature.

Which would be called if you coded

object obj = GetData(Guid userId, int languageId);  ?
PaulB
Well, it IS part of the signature, but not considered as different for normal overload resolution.
Maximilian Mayerl
This might be useful -> http://msdn.microsoft.com/en-us/library/aa691131%28VS.71%29.aspx
AB Kolan
Interesting, so C# considers it as not part of the signature? That contradicts a bit to what C# allows you for conversion operators though, they are allowed to only differ in return type and are in fact normal static methods. In .NET, the return type is a normal part of the methods signature.
Maximilian Mayerl
No, he's highlighting the problem as var/object obj = GetData(...) is a legal call and cannot be resolved to a particular method. You will have to change the name or the parameters.
ck
Although it makes less sense for something that is an accessor, in the general case calling the method for side-effects and discarding the return (e.g. just GetData(Guid.Empty,0);) makes the point even more directly.The same reasoning also applies to overloading in related languages like Java and C++.
Steve Gilham
@ Maximilian Mayerl : (From the link in the commments) The signature of a method consists of the name of the method and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of a method specifically does not include the return type, nor does it include the params modifier that may be specified for the right-most parameter. HTH
PaulB
@Maximilian: The CLR *does* consider the return type as part of the method signature. However, the syntax of C# is such that the language compiler cannot resolve the ambiguity, therefore the compiler disallows it. Conversion operators are a special case because the compiler *can* resolve them unambiguously, so they are allowed to differ in return type. Same goes for VB.NET.
Christian Hayter
+5  A: 

In C#, it's not allowed to have method overloads that differ only by their return types (with the exception of conversion operators though).

Just create two different methods, that's the only way to get around this.

Maximilian Mayerl
Can't do it in C++, either
warren
+10  A: 

You can't override based on the return-type. If you look at your method signature, it looks like the following:

public static List<SomeDTO> GetData(Guid, int)

and

public static List<int> GetData(Guid, int)

What you need to do is one of the following:

  • Change the method names to something clearer.
  • Make sure that the parameters can identify which method to call

Now, when you call your function, the return type isn't specified. And since the parameters look the same, the compiler doesn't know which function to call. But it doesn't need to make a guess, since the signatures are too similar it complains on compilation.

PatrikAkerstrand
+2  A: 

Method overloading only looks at the name of the method and the number and type of it's parameters, not at the type of the return value. That's why you get the error.

If both functions do more or less the same thing, you might solve this by making a generic function, something like:

public static List<T> GetData<T>(Guid userId, int param2)

But that does not seem to be the case in your example.

Peter van der Heijden
A: 

As PaulB said, this is because the return type is not a part of the signature when it comes to overloading. It sees both functions as:

public static List<SomeDTO> GetData(Guid userId, int languageId) -> GetData(Guid, int)
public static List<int> GetData(Guid userId, int iNumberOfItems) -> GetData(Guid, int)
kitchen
+1  A: 

The other answers here are all valid.

In this case I would recommend to change the method name of the second, as it really has a logical difference in what it does. You just don't get the "data", you specifically gets the ID's of the total dataset:

public static List<SomeDTO> GetData(Guid userId, int languageId)
{
  // Do something here
}
public static List<int> GetDataIds(Guid userId, int iNumberOfItems)
{
  var result = GetData(userID, 0);

  return (from r in result select c.id).Take(iNumberOfItems).ToList<int>();
}

Usage:

List<int> ids = GetDataIds(userID, 10);

You could also use same method name, but add a parameter:

public static List<int> GetData(Guid userId, int languageId, int iNumberOfItems)
{
  var result = GetData(userID, languageId);

  return (from r in result select c.id).Take(iNumberOfItems).ToList<int>();
}

Usage:

List<int> ids = GetData(userID, 0, 10);

Extension methods

Additionally, you could also extend List<SomeDTO> so you can call it directly if you already have a populated list of type List<SomeDTO>:

public static List<int> GetDataIds(this List<SomeDTO> data, Guid userId, int iNumberOfItems)
{
  return (from r in data select c.id).Take(iNumberOfItems).ToList<int>();
}

Then you can use it like this:

List<SomeDTO> result = GetData(userID, 0);

// do other stuff here using other aspects of the result...

List<int> ids = result.GetDataIds(userID, 10);
awe