Je soupçonne que la réponse est non, mais je veux savoir s'il est possible de faire quelque chose comme ceci: ce que je veux indiquer dans l'exemple ci-dessus (non fonctionnel) est de contraindre Jusqu'ici, j'ai piraté cela ensemble: p> ceci plus ou moins applique la contrainte que je veux (que En outre, le hack ci-dessus est brisé car un appelant pourrait en théorie Spécifier une sous-classe de Y a-t-il un moyen meilleur / plus élégant d'atteindre ce que je suis après ici? p> p> tsomeinterface code> de telle sorte qu'il peut s'agir d'une classe de base, d'une interface mise en œuvre ou (si vous voulez vraiment avoir envie de gêner) une conversion implicite de myGenericClass code>. P> tsomeinterface code> est, tant qu'il est implémenté par Tsomeclass code>. P> Tsomeclass code> doit hériter de, ou dans le cas d'une interface, de mettre en œuvre, < Code> TsomeInterface Code>), mais l'appelant est très maladroit, car je dois spécifier TintermediateType Même si je veux vraiment que cela évalue contre Tsomeclass code>): < / p> Tsomeclass code> comme premier paramètre de type, où seul la sous-classe implémente tsomeinterface code>. p>
3 Réponses :
La façon dont j'ai pu envelopper ma tête autour de la raison pour laquelle cela ne compile pas est le suivant:
considère que ce programme compile: p> tout est bon. Le compilateur est heureux. On considère maintenant que je change la méthode code> principale p> static void Main(string[] args) {
var inst = new MyGenericClass<Class1>();
inst.MyGenericMethod<Class2>();
}
Dans mon monde idéal, ce serait l'appel de la méthode bien sûr, comme si vous essayez de le faire: var x = nouvelle liste
Comme indiqué dans Cette question liée , Vous ne pouvez pas utiliser de paramètre de type qui ne se situe pas de la déclaration actuelle, à gauche d'un ainsi comme suggéré par W0LF dans cette autre question, ce que vous pouvez faire Fournit les deux types de votre interface (plutôt que la méthode) DÉCLARATION: P> où code> clause. public class MyGenericClass<TSomeClass> {
public static void MyGenericMethod<TSomeClass, TSomeInterface>
(MyGenericClass<TSomeClass> that)
where TSomeClass : TSomeInterface
{
// use "that" instead of this
}
}
Une méthode d'extension fournit la meilleure solution, bien qu'elle ne résolvait pas totalement toutes vos préoccupations.
var myGenericInstance = new MyGenericClass<TSomeClass>(); myGenericInstance.MyGenericMethod<TSomeClass, TSomeInterface>();
Ceci est pratiquement impossible puisque vous essayez de mélanger des génériques avec le temps d'exécution.
Non, je ne suis pas. Je viens d'essayer d'appliquer une contrainte générique qui (autant que je puisse dire) la langue C # ne permet pas (contraignant un paramètre de type de type, il s'agit d'une superclasse ou d'une interface mise en œuvre d'un paramètre de type dans la classe contenant).
Pour autant que je sache, vous essayez de contraindre la classe générique basée sur les données de type que vous utilisez à une méthode. Si vous souhaitez contraindre votre classe générique, vous devez le faire sur un niveau de classe (logiquement), il n'existe aucun moyen pour le compilateur JIT de créer une classe concrète.
J'essaie de contraindre le paramètre de la méthode, mais je le fais en arrière de l'ordre normal. Plutôt que
TsomeInterface Code> hériter de ou implémenterTsomeclass code>, je veux qu'il soit contraint de l'ensemble des classes de base et des interfaces implémentées deTsomeclass code>.Ahh je vois maintenant, désolé pour le problème :)
@RJlohan, veuillez indiquer votre réponse, je pense que vous pouvez être sur la bonne voie!
J'assume une interface mobile jusqu'à la classe
myGenericClass code> ne fonctionne pas pour votre cas? (serait un trival de mettre la restriction ...) @Alexeilevenkov Il fait et, en réalité, c'est presque certainement la façon dont je vais résoudre cela dans mon code de code. À ce stade, c'est vraiment plus une question académique pour moi.
@Alexeilevenkov qui dit, il y a des cas de monde réel où cela ne le résoudrait pas. Imaginez que si vous vouliez appeler n méthodes sur myGenericClass, où n est arbitrairement> 1, et pour chacun de vous souhaiter fournir une interface différente.
Je vois. Je ne peux penser à rien de bacause Il n'y a pas de relation entre Tsomeclass et Tsomeinterface, il n'y aurait donc pas de moyen de convaincre le compilateur autrement. J'essaye d'essayer quelque chose de classe supplémentaire à appeler la méthode comme
CLASS MODYCALLER: Où T: TI CODE> et l'instanciation avec MethodCaller Code> Mais le compilateur serait ne pas être capable de comprendre si ça va :(.