使用通用类型参数时,模棱两可的方法过载



考虑以下程序:

using System;
using System.Threading.Tasks;
public class Program
{
    public static void Main()
    {
        var stringTask = Task.FromResult("sample");
        stringTask.TeeAsync(st => Task.CompletedTask).Wait();
    }
}
public static class FunctionalExtensions
{
    public static async Task<T> TeeAsync<T>(this T source, Func<T, Task> asyncAction)
    {       
        await Task.Delay(0); // todo: do something with source
        return source;
    }
    public static async Task<T> TeeAsync<T>(this Task<T> asyncSource, Func<T, Task> asyncAction)
    {
        var source = await asyncSource;
        await Task.Delay(0); // todo: do something with source
        return source;
    }
}

第9行上的编译器错误,其中TeeAsyncstringTask上被调用,因为

呼叫在以下方法或属性之间是模棱两可的:'functionAlextensions.teeasync&lt; t&gt;(t,f,func&lt;任务&gt;('

从每个过载中删除第二个参数突然允许编译器为第一个参数区分Task<T>T。但是,为什么第二个参数在两个过载之间相同 - 导致编译器感到困惑?

第二个参数并不相同。它们都是Func<T, Task>,但是T在每种情况下都是不同的。

首先超载具有this T source。这意味着当您这样做

Task<string> stringTask = Task.FromResult("sample");
stringTask.TeeAsync(...)

对于第一次过载,TTask<string>

第二个具有this Task<T> asyncSource。因此,在上述情况下,对于第二个过载Tstring

因为您没有在此处指定st的类型:

stringTask.TeeAsync(st => Task.CompletedTask).Wait();

st可以是Task<string>(第一个过载(或string(第二个(。编译器不知道您的意思是。如果您这样做:

stringTask.TeeAsync((string st) => Task.CompletedTask).Wait();

它将正确选择第二个。如果您这样做

stringTask.TeeAsync((Task<string> st) => Task.CompletedTask).Wait();

它将首先选择。

有趣的是,如果您实际使用st的方式,该方式将允许编译器推断出是string还是Task<string>,则可以做到这一点。例如,这将编译并选择第二个超载:

// we don't specify st type, but using Length property
// which only exists on string
stringTask.TeeAsync(st => Task.FromResult(st.Length)).Wait();

这将首先编译并选择:

// we don't specify st type, but using Result property
// which only exists on Task<string>
stringTask.TeeAsync(st => Task.FromResult(st.Result)).Wait();

但是,如果您使用两者都存在的东西,它将再次(正确地(选择一个过载:

// ToString() exists on both string and Task<string>
// so doesn't help compiler to choose
stringTask.TeeAsync(st => Task.FromResult(st.ToString())).Wait();

相关内容

  • 没有找到相关文章

最新更新