[英]Lambda expression arguments for Enumerable and Queryable extension methods
[英]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.