views:

238

answers:

2

I was trying to create an extension that could slice any array-like class (since slicing is oddly absent in the standard libraries). For example:

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

However, the compiled does not attach this method to objects of type M (even though its error message claims that that is what it is looking for). It seems rather to be dependent upon the type parameters of the method itself, e.g. in some manner, but I don't fully understand how things are working.

(yes, one could easily write an example that just works with List, but I'm curious if this is even possible.)

+3  A: 

There compiler does not infer the type T automatically for these cases. Even if it wasn't an extension method, you still had to specify the type parameters manually.

For example what if the class was declared as:

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

What would you expect T to be? int or double? As a result, you'll always have to manually call it with the specific parameters:

Slice(myList, 0, 10); // compile-time error, T cannot be inferred.
Slice<IList<int>, int>(myList, 0, 10); // works.

The workaround is to remove the type parameter T (no constraints needed here):

public static void Slice<M>(this IList<M> source, int start, int end)

By the way, note that, this is by no means related to the number of parameters. You can have as many type parameters as you like, as long as the compiler can infer them (according to C# specification generic type inference rules). For example, this extension method can be called without specifying type arguments:

public static void SomeMethod<T,U>(this IEnumerable<T> collection, U anotherParameter)
Mehrdad Afshari
A: 

Have you looked at the List.GetRange method?

SolutionYogi
Yes, sorry, I was doing a deep copy. Otherwise GetRange is perfect.
Ender