簡體   English   中英

使用泛型類型參數時,不明確的方法會重載

[英]Ambiguous method overloads when using generic type parameters

考慮以下程序:

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行上的編譯器錯誤,其中在TeeAsync上調用stringTask因為

以下方法或屬性之間的調用不明確:'FunctionalExtensions.TeeAsync <T>(T,Func <T,Task>)'和'FunctionalExtensions.TeeAsync <T>(Task <T>,Func <T,Task>) “

從每個重載中刪除第二個參數突然允許編譯器區分第一個參數的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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM