J'ai une classe qui est générée par certains outils, je ne peux donc pas le changer. La classe générée est très simple (aucune interface, pas de méthodes virtuelles): dans le projet C #, nous voulons fournir un moyen de pouvoir brancher une autre implémentation de MyFoo. Donc, je pense que je pense que myfoo dérivé de générationfoo p> puis j'ai une méthode Createefoo qui renvoie une instance de la classe Generatedfoo ou MyFoo. Cependant, il appelle toujours la méthode en générationfoo. P> GeneratedFoo foo = CreateFoo(); // if this returns MyFoo,
foo.Write("1"); // it stills calls GeneratedFoo.Write
7 Réponses :
Sans pouvoir faire la méthode virtuelle, non. Une méthode non virtuelle est statiquement liée au moment de la compilation et ne peut pas être modifiée. p>
Si la classe générée n'a pas de méthode virtuelle, il n'est pas possible. Si vous pouviez modifier l'outil pour générer la méthode d'écriture sous forme virtuelle, alors dans MyFoo, utilisez le mot-clé de remplacement au lieu de neuf pour qualifier la méthode d'écriture. Une deuxième option serait d'écrire un script / macro pour modifier le code source de générationfoo après l'exécution de l'outil pour injecter la chaîne "virtuelle" avant les méthodes souhaitées dans le cadre de votre processus de construction. P>
Adam vous a donné une réponse (correcte). Maintenant, il est temps de demander que vous demandiez :) imprime: p>
Il n'y a pas besoin de dangereux là-bas
Aye, ce dangereux est ici parce que j'ai peu de projets «tests» que j'ouvrant dans VS lorsque j'ai besoin de cuisiner un code vraiment étrange, alors principal est dangereux par défaut et j'ai également beaucoup d'étrange usings là-bas hehe.
Quoi qu'il en soit, peu sûr enlevé pour la clarté (comme il est juste obsolète), merci de la commenter.
L'utilisation de la réflexion est sloooooooow et complètement inutile. De plus, il est préférable d'éviter de s'appuyer sur des cordes magiques autant que possible. Je recommande d'utiliser la méthode d'extension de Tullo (sur cette page) pour obtenir le même résultat.
@Michaelgraczyk Vous avez raison sur les préoccupations de vitesse bien sûr. Cependant, ma solution diffère de Tullo's, car elle appellera toujours la méthode "droite". Où "droit" est la mise en œuvre du type de type sous-jacent, même si vous avez une chaîne d'héritage (vous devez donc vérifier chaque type de base en chaîne et trouver le plus de base). De plus, si vous avez besoin d'une vitesse, car vous appellerez cette méthode souvent, vous pouvez créer un délégué à partir de getMethod ("") une fois la méthode valide. Néanmoins, je suis d'accord, que c'était un hack, principalement de montrer que vous avez la possibilité de faire une telle chose.
Il est vrai que le vôtre est plus "droit" en ce qui concerne la sémantique d'expédition attendue. Je suppose quelque chose qu'il allait seulement dériver de la classe génératrice d'un niveau de classe unique. Je vous ai + 1 de toute façon.
Impressionnant - Merci - J'utilise ce problème sous Windows Formulaires pour itérer une collection de contrôles personnalisés ajoutés à une table de manière dynamique. J'ai 28 types de contrôle différents et l'autre option aurait été d'itérer si tous les types différents. Cela m'a sauvé au moins 150 lignes de code ... plus si j'ajoute plus de types de contrôle plus tard, ils vont simplement travailler.
Une approche que vous pourriez utiliser serait de définir réellement quelques nouvelles classes dérivées de GénériqueFoo; Par exemple: Cela vous permettrait d'ajouter essentiellement des méthodes virtuelles à votre classe générée. p> p>
Mais non invoquer la méthode non virtuelle de FOO générée comme ce serait virtuel.
Mais vous pouvez écrire une nouvelle méthode qui était virtuelle et appelée le non crucial de la classe dérivée que vous vouliez avoir ce comportement et n'a pas appelé le non crucial de la classe dérivée qui ne devrait pas avoir ce comportement.
Utiliser "Nouveau" sur une méthode ne remplace pas, sa cause de la méthode d'origine. Ceci est complètement différent du polymorphisme et doit être évité, son seul objectif concerne la covariance / la contre-variance des méthodes qui effectuent une fonction identique (par exemple, le clone public public (); et le nouveau clone de barres (); L'autre objectif est pour le code hérité lorsqu'une méthode nommée identique est ajoutée à une classe de base que vous n'avez pas de contrôle et ne peut pas à ce moment changer le nom de votre méthode.
Bien que les deux méthodes partagent le même nom, ils sont des méthodes complètement distinctes Il occupe une fente différente dans la table de la méthode de la classe, où la méthode existante remplace la méthode existante dans la table de la méthode d'une classe. P>
Ma solution consiste à utiliser une interface telle que IFOO et éditer Classe générée ou utilise une classe de proxy qui déléguette toute sa méthode appelle à une instance de générationfoo pour mettre en œuvre ifoo. p>
Écrivez une méthode d'extension qui se confond à votre type dérivé et appelle la méthode contre que em> référence em>. puis appelez-le avec p> < Pré> xxx pré> nb strong>: C'est un hack sale. Une solution plus claire serait de vous demander pourquoi em> vous devez utiliser le modificateur nouveau code> en premier lieu. Surcharger la signification de écrire (p) code> rendra votre code déroutant pour les mainteneurs. Vous pouvez tout aussi facilement le déclarer Public Void Writetotarget () Code> ou quelque chose de beaucoup plus spécifique pour éviter cette confusion en premier lieu. P> P>
Qu'en est-il d'une règle de code FX personnalisée ajoutée à votre système de construction? p>
"NOUVEL NOUVELLIQUE PUBLIQUE"? C'est une utilisation de "nouveau" que je n'ai jamais vu auparavant. Est-ce même valable?
«Nouveau» ici indique que vous avez explicitement «couvert» de la classe de base, sans le remplacer (car ce n'est pas virtuel) - sans cela, vous obtiendrez réellement un avertissement de compilateur.
Pour être plus précis - lorsque vous donnez votre méthode de classe dérivée le même nom que dans la base, et ce n'est pas la méthode de remplacement, les compilateurs vous avertissent que votre méthode cache-t-elle un membre hérité (parce que vous n'avez probablement pas voulu le faire) , mais si vous en êtes sûr, vous le disez au compilateur à l'aide de «nouveau» mot-clé.
Je suis toujours ravi lorsque des mots-clés sont surchargés pour avoir plusieurs significations en fonction du contexte. Merci de m'avoir corrigé.