2009-07-08 19 views
1

Ich habe versucht, eine Erweiterung zu erstellen, die jede Array-ähnliche Klasse schneiden könnte (da Slicing in den Standardbibliotheken seltsam abwesend ist). Zum Beispiel:C#: Mehrere Typparameter in Extensions

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

Allerdings ist die kompiliert nicht diese Methode, um Objekte vom Typ M befestigen (auch wenn seine Fehlermeldung behauptet, dass das ist, was es sucht). Es scheint eher von den Typparametern des Verfahrens selbst abhängig zu sein, z. in gewisser Weise, aber ich verstehe nicht ganz, wie die Dinge funktionieren.

(ja, könnte man leicht ein Beispiel schreiben, die nur mit Liste funktioniert, aber ich bin neugierig, ob dies überhaupt möglich ist.)

Antwort

3

Es Compiler schließen nicht den Typ T automatisch für diese Fälle. Auch wenn es sich nicht um eine Erweiterungsmethode handelte, mussten Sie die Typparameter dennoch manuell angeben.

Zum Beispiel was passiert, wenn die Klasse wurde erklärt:

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

Was würden Sie erwarten T sein? int oder double? Als Ergebnis haben Sie immer manuell mit den spezifischen Parametern aufzurufen:

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

Die Abhilfe ist es, den Typ-Parameter T (keine Einschränkungen Probleme mehr) zu entfernen:

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

Durch die Übrigens, das hängt keineswegs mit der Anzahl der Parameter zusammen. Sie können so viele Typparameter haben, wie Sie möchten, solange der Compiler sie ableiten kann (gemäß den generischen Typinferenzregeln der C# -Spezifikation). Zum Beispiel kann diese Erweiterung Methode ohne Angabe Typargumente aufgerufen werden:

public static void SomeMethod<T,U>(this IEnumerable<T> collection, U anotherParameter)