J'ai la méthode suivante: et cette classe p> Je ne peux pas utiliser de paramètres de type générique comme celui-ci? Comment résoudre ce problème? image plus large (pas nécessaire pour répondre à la question!) : strong> Pour vous assurer que cette méthode ne peut être appelée que par des paramètres entièrement configurés, il n'accepte que un Les appels suivants seraient des appels valides: p> Ce qui suit serait invalide: p> pour effectuer ce travail, il existe des méthodes d'extension nommées
chaîne code>. li>
nouvel événementInvocatorParameterers
Point important: J'ai besoin de ces deux paramètres génériques, car je dois renvoyer le même type que cette méthode d'extension a été appelée. P> <<
J'essaie de créer une interface fluide pour invoquer des événements. La base est cette classe statique: p> configureDeventInvocatorParamètres
EventInvocatorParameters
avec code>, qui acceptent soit un
EventHandler
TEventInvocatorParameterers CODE> et renvoie un
ConfigurationDeventInvocatorParamètres
configurationEventInvocatorParameters
jusqu'à code> à la fin) ne fonctionnerait pas.
Si vous avez des idées sur l'API en général, faites-le-moi savoir. Cependant, je veux éviter les trois choses suivantes: p>
EventName.with (...). Jusqu'à (...). Feu () Code> Li>
do code> pour démarrer les choses:
feu (eventName) .with (...). Jusqu'à (...). DO (); code> li>
ul> p>
4 Réponses :
y a-t-il une raison pour laquelle vous besoin em> utiliser une méthode d'extension? Si vous mettez jusqu'à code> sur la classe
EventInvocatorParameters
public class EventInvocatorParameters<T>
where T : EventArgs
{
public Func<T, bool> BreakCondition { get; set; }
// Other properties used below omitted for brevity.
public EventInvocatorParameters<T> Until (Func<T, bool> breakCond)
{
this.BreakCondition = breakCond;
return this;
}
}
Oui, il y a une raison. Il est détaillé dans la longue durée de la question intitulée «Photo plus large (pas nécessaire pour répondre à la question!)». Peut-être que c'est nécessaire après tout. Version courte: jusqu'à ce que code> soit appelé une classe dérivée de
EventInvocatorParameters
jusqu'à code> être ce type dérivé.
Le type de méthode générique Inference fait délibérément pas em> apporter des déductions des contraintes. Les déductions sont plutôt fabriquées à partir des Arguments em> et les paramètres formels , puis les arguments de type déduites sont vérifiés contre les contraintes. P>
Pour une discussion détaillée de certains des problèmes de conception autour des contraintes et des signatures de méthode, y compris plusieurs dizaines de personnes qui me disent que je me trompe de penser que la conception existante est sensible, voir mon article sur le sujet: P>
J'ai aimé cette partie de votre réponse: "Y compris plusieurs dizaines de personnes me disant que je me trompe de penser que le design existant est sensible"! :-) Soins pour fournir une alternative qui atteint ce que je veux?
Et BTW: Je suis d'accord avec eux. Sans vouloir redémarrer cette discussion: ce que vous dites est le meilleur match pourrait être techniquement tellement, mais intuitivement, ce n'est pas le cas. Toutes les réponses vous disent que vous avez tort de faire suffisamment de preuve. Votre point principal est invalide à mon avis. Il n'y a pas de deviner. Je suis tout à fait d'accord avec la réponse de David Nelson à partir de 10 déc. 2009 16h13. Votre réponse à lui n'est pas plus convaincante. Le principal problème est que le compilateur déduit un type qui n'est pas valide pour cette méthode générique.
@Daniel: Le problème est que différents scénarios peuvent pomper votre intuition dans différentes directions. Je maintiens ma position: C # est une langue qui vous dit quand quelque chose semble mal. Il n'ignore pas de problème et redevient un choix pire lorsque le meilleur choix déduit violent une contrainte.
Je sais que vous maintenez votre position. Tous ces arguments ne pouvaient pas vous faire changer, alors pourquoi devriez-vous le mien? Cependant, vous pourrait i> améliorer la compréhension si vous fournissez un échantillon qui montre en réalité ce que vous percevez comme problème. Imaginez C # aurait été mis en œuvre l'inverse, quels scénarios ne manqueraient alors d'être intuitifs? Quelles erreurs et problèmes cela causerait-il? Parce que je - et évidemment beaucoup d'autres - ne voyez pas comment cela "ignorerait un problème".
J'ai toujours eu l'intuition que les contraintes ne feraient pas partie de la signature. Je ne suis pas capable de montrer cette intuition comme causant des problèmes si c'est faux. Mon intuition est basée sur le fait que je m'attends à ce que le mot «contrainte» implique de réduire le nombre d'appels de méthode légale que je puisse faire, plutôt que de changer ce que ces appels de méthode font. J'envisage d'utiliser une contrainte sur une méthode indéfinie pour une situation particulière, mais où l'appelant comme un étranger en regardant la signature de méthode semblerait autrement un sens. Prendre avec grain de sel; Je n'utilise pas beaucoup de contraintes.
Je l'aimerais s'ils pouvaient au moins permettre au polymorphisme basé sur des contraintes de type dans ce cas: Void Foo
Imo, c'est une faille de conception. Si vous avez deux surcharges de méthode d'extension pour un type générique et que vous limitez la deuxième surcharge de type FOO, le compilateur n'est pas suffisamment intelligent pour sélectionner la première surcharge lorsque vous appelez à partir d'un objet source de type SPAM, mais il est assez intelligent de dire Vous que l'objet source ne correspond pas à la contrainte de type. L'ensemble de la raison des méthodes de vulgarisation est la commodité et il n'y a rien de pratique lorsque vous ne pouvez pas les utiliser car le compilateur n'est pas assez intelligent pour choisir la bonne surcharge, mais il est suffisamment intelligent de vous dire qu'il a choisi le mauvais.
L'article Eric lié n'est plus à cette URL. Il est disponible ici maintenant: docs.microsoft.com/en-gb/archive/blogs/ericlippert/...
@Matthewwatson: merci! Je finirai éventuellement à déplacer cela à Ericlippert.com, mais c'est un processus lent.
Bit d'une flexibilité Je sais, mais avez-vous envisagé d'utiliser RX A > Au lieu de cela, plutôt que de réinventer ce que vous semblez essayer de faire? P>
Non, je n'ai pas. Google ne l'a pas marché pour "API d'invocation de l'événement fluide". Merci pour le pointeur, je vais examiner.
Pouvez-vous me donner un court exemple de la façon dont vous utiliseriez RX pour atteindre ce que je veux?
Pour quiconque intéressé, pour l'instant, j'ai résolu le problème initial (API d'invocation de l'événement fluide) avec une hiérarchie générique de classe. C'est essentiellement la réponse de Hightichrider sur les stéroïdes.
Fire.Event(EventName.Until(e => false)); Fire.Event(EventName);