2009-07-08 7 views
1

J'essayais de créer une extension qui pourrait trancher n'importe quelle classe de type tableau (puisque le découpage est curieusement absent dans les bibliothèques standard). Par exemple:C#: paramètres de type multiple dans les extensions

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

Cependant, la compilation ne se fixe pas cette méthode aux objets de type M (même si son message d'erreur, il en va ce qu'il est à la recherche). Il semble plutôt dépendre des paramètres de type de la méthode elle-même, par ex. d'une certaine manière, mais je ne comprends pas complètement comment les choses fonctionnent.

(oui, on pourrait facilement écrire un exemple qui fonctionne avec la liste, mais je suis curieux de savoir si cela est encore possible.)

Répondre

3

Il compilateur ne déduit pas le type T automatiquement ces cas. Même s'il ne s'agissait pas d'une méthode d'extension, vous deviez toujours spécifier les paramètres de type manuellement.

Par exemple si la classe a été déclarée comme:

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

Que voulez-vous attendre T être? int ou double? Par conséquent, vous devez toujours appeler manuellement les paramètres spécifiques:

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

La solution consiste à supprimer le paramètre de type T (pas de contraintes nécessaires ici):

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

Par manière, notez que ceci n'est nullement lié au nombre de paramètres. Vous pouvez avoir autant de paramètres de type que vous le souhaitez, tant que le compilateur peut les déduire (selon les règles d'inférence de type générique C#). Par exemple, cette méthode d'extension peut être appelée sans spécifier des arguments de type:

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