J'ai les méthodes d'extension suivantes: Les interfaces génériques sont toujours dérivées de leur interface non générique correspondante. P> Malheureusement, pour faire ce travail: public static void FooBar<TResult>(
this IBar<TResult> bar, Action<TResult> action);
4 Réponses :
En supposant que vous soyez capable d'aller d'un ifoo
ifoo code> et votre chaîne de méthodes ne se soucie pas de
treesult code> Vous pourrez peut-être enregistrer une partie de la mise en œuvre en modifiant l'utilisation de quelque chose comme:
api.Foo(x => ReturnLong())
.Bars(foo=>foo.Bar1() //where foo is an IFoo
.Bar2()
.Bar3()
...
)
.FooBar(x => ...);
On pourrait faire cela, cependant, il y a beaucoup de bruit. Bien qu'il existe de nombreuses méthodes de barre () différentes, la plupart du temps, l'utilisateur va appeler exactement un et cela se traduirait .bars (foo => foo.bar ()) pour rien: / merci pour la tentative -> upvoted.
L'interface fluide au sein de C # dépend des types (explicitement ou implicitement) étant passée à travers chaque Vos seules options sont d'avoir des succursales dans vos expressions, comme décrit dans la réponse de Shawn, ou si vous devez avoir . code> fort>. Comme vous l'avez décrit, si vous perdez des informations de type, vous ne pouvez pas le récupérer. P>
ibar
.bar code> s sont en fait comme
.First code> ou
.Singleordfault code> Ils ne doivent pas être suivis par < code> .foobar code> de toute façon (au moins pas directement). LI>
ul>
Notez que le type générique doit être connu à l'heure de la compilation. Vous pouvez stocker l'instance de classe de type au moment de l'exécution mais vous pouvez 't l'utiliser à la place du paramètre générique. Vous avez créé deux types: La première solution est connue pour vous - créer une version générique de tous types que vous utilisez dans votre chaîne d'invocation. . Cela nécessite beaucoup d'effort. P> Si vous pouvez supposer, que le type ne changera pas pendant l'exécution, vous pouvez envelopper ce type et utiliser vos méthodes explicitement: p> ifoo code> et
ifoo
ibar code> est créée par le
ifoo code> qui ne dispose pas des informations sur son type, car elle n'engage aucun. Ainsi, les informations de type sont perdues. Nous ne pouvons considérer que des solutions capables de déduire le type au moment de la compilation. P>
.
.
.FooBar(x => { if (x is MyType) { /* ... */ } });
Débarrassez-vous de l'interface IFOO qui n'a pas de paramètre de type et ajoutez un paramètre de type à IBAR pour vous rappeler le type d'IFOO. Sans cela, des programmes incorrects de type chèque.
Y a-t-il une raison dans votre API fluide d'avoir les méthodes non génériques? Sinon, il suffit de les abandonner en faveur des génériques entièrement.
Pourquoi n'avez-vous pas de
Static Static ibar bar (cette IFOO FOO); code>?
@Chris: Malheureusement oui, que dois-je revenir à FOO (action)?
@supercat: Non requis par les utilisateurs, alors pourquoi le mettre en œuvre? Malheureusement, si je souhaite utiliser l'inférence de type, je dois la mettre en œuvre ... question est maintenant: comment surmonter cette faille?
Je n'appellerais pas du tout un "défaut". Je pense que votre meilleur pari est de mettre en œuvre toutes les méthodes ou de créer un constructeur générique d'emballage dans lequel le
treesult code> est défini une fois au niveau de la classe. (Ce faisant, je suppose que je veux dire cependant l'utilisation de la méthode de prolongation, et vous oblige toujours à mettre en œuvre les méthodes) Je dis simplement mordre la balle, faites-le approprié et évitez "Magic". EDIT: Désolé, je pense que je comprends bien le problème maintenant. Vous devez chaîner les informations génériques à travers des appels non génériques. Ouais, essayez de faire une classe de constructeurs distincte.
@Chris: Merci de votre réponse, cependant, il y a aussi beaucoup de barres () - comme des méthodes non écrites par moi, mais par des développeurs de vulgarisation. Je ne veux pas qu'ils ont besoin de mettre en œuvre deux méthodes.
Les types de la question de la question ne font pas appliquer la sécurité de type, si "X devrait être de type". Le suivant Typecheck: Action stringaction = console.writeine; api.foo (x => retourlong ()). bar (). Foobar (stringaction);
@ D.R. Si vous abandonnez les interfaces non génériques, vous utiliseriez l'unité code> type code> comme T. L'unité code> type code> est le type avec une seule valeur, qui peut être implémentée comme
Unité de structure publique {} code>. Vous remarquerez également que le compilateur ne peut pas discerner entre les surcharges de
action code> et
Func <> code> ou entre
action code> et
et
et
Func code>, vous voudrez donc renommer l'un des
foo code> s.