c# – 使用泛型类型参数时模糊方法重载
作者:互联网
考虑以下程序:
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行上的编译器错误,其中在stringTask上调用TeeAsync,因为
The call is ambiguous between the following methods or properties: ‘FunctionalExtensions.TeeAsync<T>(T, Func<T, Task>)’ and ‘FunctionalExtensions.TeeAsync<T>(Task<T>, Func<T, Task>)’
从每个过载中移除第二参数突然允许编译器区分Task< T>.和T表示第一个参数.但是为什么第二个参数 – 两个重载之间相同 – 会导致编译器混淆?
解决方法:
第二个参数不相同.它们都是Func< T,Task>,但在每种情况下T都不同.
第一次重载有这个T源.这意味着当你这样做
Task<string> stringTask = Task.FromResult("sample");
stringTask.TeeAsync(...)
对于第一次重载,T是Task< string>.
第二个具有该任务< T> asyncSource.所以在上面的情况下,对于第二个过载,T是字符串.
因为您没有在此处指定st的类型:
stringTask.TeeAsync(st => Task.CompletedTask).Wait();
st可以是Task< string> (第一次重载)或字符串(第二次).编译器无法知道你的意思.如果你这样做:
stringTask.TeeAsync((string st) => Task.CompletedTask).Wait();
它会正确选择第二个.如果你这样做
stringTask.TeeAsync((Task<string> st) => Task.CompletedTask).Wait();
它会先选择.
有趣的是,如果您实际使用st的方式将允许编译器推断它是否是字符串或任务< 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();
标签:c,net,overload-resolution,generics 来源: https://codeday.me/bug/20190522/1153053.html