Reputation: 13723
I'm not sure exactly how to call this situation, but here it is:
I have 2 methods with different types, but from the "outside" they have the same signature. And when calling the method, I would like to invoke a specific method instead of the other - here is what I have:
public class SomeClass
{
public async Task<Response<T>> MyMethod<T>(string name, T myObj)
{
// some code here
}
public async Task<Response<T>> MyMethod<T>(string name, string myObj)
{
// some code here
}
}
For the compiler, the 2 methods above are different and have different signatures. But when calling:
var myClass = new SomeClass();
myClass.MyMethod("name", "something");
When calling MyMethod
in the example, what's being called is MyMethod<T>(string name, T myObj)
, but what I would actually want to call is the second method. Is there a way to make it call a specific signature?
EDIT:
I found the if I give in one of the methods a different name to the second variable and then calling the method with the variable name as part of the call it does work, as in the following example:
public class SomeClass
{
public async Task<Response<T>> MyMethod<T>(string name, T myObj)
{
// some code here
}
public async Task<Response<T>> MyMethod<T>(string name, string myNewObj)
{
// some code here
}
}
var myClass = new SomeClass();
myClass.MyMethod<AnyOfMyTypes>("name", myNewObj: "something");
While this works, following Jon's response below, does it seem like something that is correct to do? As far as for the method name, I would like to keep it the same, and the other option is to change the signature by adding some dummy boolean
variable.
Upvotes: 7
Views: 1163
Reputation:
The reason the first method is being called is because you have a generic type of T. If you pass a string into this then it will hit the first method. It is better design to only have one method. If you want to be able to pass in any type then keep the first method, if you want just a string then keep just the second method. You should only have two methods if both have distinct clear purposes.
This
public class SomeClass
{
public async Task<Response<T>> MyMethod<T>(string name, T myObj)
{
// some code here
}
}
Or
public class SomeClass
{
public async Task<Response<T>> MyMethod<T>(string name, string myObj)
{
// some code here
}
}
Or
public class SomeClass
{
public async Task<Response<T>> MyMethod<T>(string name, string myObj)
{
// some code here
}
public async Task<Response<T>> MyMethod<T>(string name, int age, string address)
{
// some code here
}
}
Dont put a dummy variable into any of the methods, this will lead to problems debugging and be misleading for other developers.
Upvotes: 1
Reputation: 37430
Following Jon's answer I'd suggest following solution to your problem:
private async Task<Response<T>> MethodForString<T>(string str)
{
// some code...
}
public async Task<Response<T>> Method<T>(T obj)
{
if (typeof(T) == typeof(string))
return MethodForString<T>(obj as string);
// some code...
}
Above is just a sample, but idea is simple: just check type of T
and call appropriate method :)
This way, all your method call will remain exactly the same :)
Upvotes: 1
Reputation: 1502156
The compiler certainly can't call the second method with that calling code, as it wouldn't know what to infer for T
. If you specify a type argument though, it does call the second method:
myClass.MyMethod<string>("name", "something");
While that will work, I would strongly advise you to change the design if you possibly can. Rename one of the methods. I can reasonably call myself a C# expert, but I couldn't predict from inspection whether or not that would work. The overload resolution and type inference details in C# are really complicated, and it's unreasonable to expect every C# developer to know them inside out.
If you can give the methods different names, the code code is likely to be a lot simpler to read.
Upvotes: 11