2009-07-08 81 views
1

我试图创建一个扩展,可以切片任何数组类(因为在标准库中奇怪地缺少切片)。例如:C#:扩展中的多个类型参数

public static M Slice<M,T>(this M source, int start, int end) where M : IList<T> 
{ 
    //slice code 
} 

但是,编译此方法并不重视M型的对象(即使它的错误消息,声称这是它正在寻找)。它似乎相当依赖于方法本身的类型参数,例如,以某种方式,但我不完全理解事情是如何工作的。

(是的,我们可以很容易地写,仅仅在名单工作的例子,但我很好奇,如果这甚至有可能。)

回答

3

有编译器不会对这些情况推断类型T自动。即使它不是扩展方法,您仍然需要手动指定类型参数。

例如,如果什么类被声明为:

class MyNastyClass : IList<int>, IList<double> { 
} 

什么,你会期望T是? intdouble?其结果是,你将永远有具体参数手动调用它:

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)