Reputation: 2039
I have two functions that take in different Func
parameters. The compiler is telling me it can't differentiate between these functions.
1)
public static async Task<TResult> SomeMethodName<TSource, TResult>
(Func<TSource, Task<TResult[]>> FunctionToRun)
2)
public static async Task<TResult> SomeMethodName<TSource, TResult>
(Func<TSource, Task<TResult>> FunctionToRun)
The difference is slight - but it seems that the C# compiler is not picking it up and can't tell the difference.
Is there a reason why Func<...>
type parameters' don't get checked?
Error is on this line:
var data = await SomeMethodName<model, model2>(someModel, SomeOtherMethod);
SomeOtherMethod method:
public static Task<model2[]> SomeOtherMethod(model model)
{
Task<model2[]> data = SomeThirdMethodThatReturnsTasks(model);
return data;
}
Error Details:
The call is ambiguous between the following methods or properties:
SomeMethodName<model,model2>(model,System.Func<model,System.Threading.Tasks.Task<model2[]>>)
and
SomeMethodName<model,model2>(model,System.Func<model,System.Threading.Tasks.Task<model2>>)
Upvotes: 0
Views: 438
Reputation: 203839
There is nothing preventing the type of TResult
from being an array.
Let's take this example use of the method for a second:
var task = SomeMethodName((int i) => Task.FromResult(new[] { i }));
This code compiles and runs correctly if only the second method is defined. In that case you're calling:
SomeMethodName<int, int[]>(Func<int, Task<int[]>> FunctionToRun)
The cod would also compile and run successfully if you only have the first method defined. then you have:
SomeMethodName<int, int>(Func<int, Task<int[]>> FunctionToRun)
Since generic arguments aren't a part of the signature, these two functions are identical for the purpose of overload resolution. If both of the overloads exist then overload resolution identifies both of them as valid methods, and there is nothing that makes either one of them "better' than the other based on the defined "betterness" criteria. Since it has no way of picking one, it results in a compiler error due to the ambiguity.
Upvotes: 1
Reputation: 56576
The problem isn't with inferring TResult
, it's with TSource
. When you have a lambda like:
SomeMethodName(x => x.Something);
C# has no idea what x
is unless you tell it. Once you specify that, it should be unambiguous to the compiler:
SomeMethodName<string, int>(x => x.Something); // or
SomeMethodName<string, int[]>(x => x.Something);
Upvotes: 0