C#Func参数重载 - 不明确

时间:2014-07-25 16:29:13

标签: c# parameters func

我有两个函数可以使用不同的Func参数。编译器告诉我它无法区分这些函数。

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)

差别很小 - 但似乎C#编译器没有把它拿起来,也无法分辨出来。

是否有理由不检查Func<...>类型参数?


编辑 - 添加用户方法呼叫代码:

错误在这一行:

var data = await SomeMethodName<model, model2>(someModel, SomeOtherMethod);

SomeOtherMethod方法:

public static Task<model2[]> SomeOtherMethod(model model)
{
    Task<model2[]> data = SomeThirdMethodThatReturnsTasks(model);
    return data;
}

错误详情:

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>>)

2 个答案:

答案 0 :(得分:1)

没有什么可以阻止TResult的类型成为数组。

让我们以此示例的方式使用该方法:

var task = SomeMethodName((int i) => Task.FromResult(new[] { i }));

如果仅定义了第二种方法,则此代码将正确编译并运行。在那种情况下,你正在打电话:

SomeMethodName<int, int[]>(Func<int, Task<int[]>> FunctionToRun)

如果您只定义了第一个方法,则cod也会成功编译并运行。那么你有:

SomeMethodName<int, int>(Func<int, Task<int[]>> FunctionToRun)

由于泛型参数不是签名的一部分,因此这两个函数在重载解析时是相同的。如果两个重载都存在,那么重载决策将它们都识别为有效方法,并且根据定义的“更好”标准,没有任何一个使它们中的任何一个“比另一个”更好。因为它无法选择一个,由于含糊不清,导致编译错误。

答案 1 :(得分:0)

问题不在于推断TResult,而是TSource。当你有一个lambda像:

SomeMethodName(x => x.Something);

除非你说出来,否则C#不知道x是什么。指定后,编译器应该是明确的:

SomeMethodName<string, int>(x => x.Something); // or
SomeMethodName<string, int[]>(x => x.Something);