簡體   English   中英

可枚舉派生類上的擴展方法無法推斷類型 arguments

[英]Extension methods on enumerable-derived classes cannot infer type arguments

我們目前正在與 generics 合作開發可枚舉派生類的擴展。 顯然,如果在從IEnumerable<T>派生的 class 上調用擴展方法並返回包含T類型的值,則編譯器會產生錯誤 CS0411 和擴展方法。

以下示例重現了該錯誤:

public class Item { }

public class CollectionType : IEnumerable<Item>
{
    public IEnumerator<Item> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

public static class CollectionExtension
{
    public static T[] DoSomething<T, TCollection>(this TCollection source)
        where TCollection : IEnumerable<T>
    {
        throw new NotImplementedException();
    }
}

public class Test
{
    public void TestMethod()
    {
        var collection = new CollectionType();

        collection.DoSomething();

        collection.DoSomething<Item, CollectionType>(); // This works fine
    }
}

調用DoSomething()將產生以下錯誤:

The type arguments for method 'T[] [...].CollectionExtension.DoSomething<T,TCollection>(this TCollection)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

如果TCollection被綁定為IEnumerable<T>類型並且T也被定義為DoSomething()的泛型類型參數,這怎么會發生?

CollectionType上調用擴展方法應該為DoSomething()提供兩種泛型類型。

如果不明確指定泛型類型,就不可能按原樣使用DoSomething()方法。 class IEnumerable<T>似乎可以從中推斷出T的類型位於類型約束聲明中,不幸的是 C# "...cannot infer the type parameters only from a constraint or return value" 在此處查看詳細信息:

[https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-methods]

這個問題可以通過不同的方式解決,您可以像在示例代碼中那樣顯式指定類型 - collection.DoSomething<Item, CollectionType>() ,或者向DoSomething()添加類型為T的參數,在這種情況下 C# 將能夠推斷類型,或擺脫泛型類型 TCollection,用IEnumerable<T>以下列方式替換它:

public static T[] DoSomething<T>(this IEnumerable<T> source)
{
    throw new NotImplementedException();
}

我認為最后一個會是一種更清潔的方式。

暫無
暫無

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

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