[英]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.