我试图创建一个可以切片任何类似数组的类的扩展(因为在标准库中奇怪地没有切片)。例如:
public static M Slice<M,T>(this M source, int start, int end) where M : IList<T>
{
//slice code
}
但是,编译时不会将此方法附加到类型为M的对象(即使其错误消息声称它正在寻找它)。似乎更依赖于方法本身的类型参数,例如,以某种方式,但我不完全了解事情是如何运作的。
(是的,有人可以轻松编写一个与List一起使用的示例,但我很好奇这是否可能。)
答案 0 :(得分:3)
对于这些情况,编译器不会自动推断类型T
。即使它不是扩展方法,您仍然必须手动指定类型参数。
例如,如果该类被声明为:
class MyNastyClass : IList<int>, IList<double> {
}
您期望T
会是什么? int
或double
?因此,您始终必须使用特定参数手动调用它:
Slice(myList, 0, 10); // compile-time error, T cannot be inferred.
Slice<IList<int>, int>(myList, 0, 10); // works.
解决方法是删除类型参数T
(此处不需要约束):
public static void Slice<M>(this IList<M> source, int start, int end)
顺便提一下,请注意,这与参数的数量无关。您可以拥有任意数量的类型参数,只要编译器可以推断它们(根据C#规范通用类型推断规则)。例如,可以在不指定类型参数的情况下调用此扩展方法:
public static void SomeMethod<T,U>(this IEnumerable<T> collection, U anotherParameter)
答案 1 :(得分:0)
你看过List.GetRange method了吗?