J'obtiendrai probablement une réponse négative ici, mais j'aimerais poser ma question.
Y a-t-il un moyen en C # d'appeler la méthode parente avant (ou après) TOUTE méthode de classe enfant.
public class Base { protected static void ThisWillBeCalledBeforeAnyMethodInChild() { //do something, e.g. log } protected static void ThisWillBeCalledAFTERAnyMethodInChild() { //do something, e.g. log } } public class SomeClass : Base { public static void SomeMethod1() { //Do something } public static void SomeMethod2() { //Do something } }
Donc, je veux méthode ThisWillBeCalledBeforeAnyMethodInChild
depuis la classe de base pour l'exécuter avant SomeMethod1
ou SomeMethod2 code> dans
SomeClass
. Similaire avec la méthode after.
Y a-t-il un moyen de le faire sans appeler des méthodes avec réflexion?
3 Réponses :
Tout d'abord, les méthodes statiques ne participent pas à l'héritage.
Vous avez un contrôle total sur cela en utilisant le pointeur de base, qui est une référence à la classe de base du pointeur this.
class Program { static void Main(string[] args) { var s = new SOmeClass(); s.SomeMethod1(); s.SomeMethod2(); } } public class Base { protected void ThisWillBeCalledBeforeAnyMethodInChild() { Console.WriteLine("ThisBefore"); } protected void ThisWillBeCalledAFTERAnyMethodInChild() { Console.WriteLine("ThisAFTER"); } } public class SOmeClass : Base { public void SomeMethod1() { base.ThisWillBeCalledBeforeAnyMethodInChild(); Console.WriteLine("SomeMethod1"); } public void SomeMethod2() { Console.WriteLine("SomeMethod2"); base.ThisWillBeCalledAFTERAnyMethodInChild(); } }
Sortie :
ThisBefore SomeMethod1 SomeMethod2 CeciAFTER
"Tout d'abord, les méthodes statiques ne participent pas à l'héritage." Comment es-tu arrivé à cette conclusion? changez le protected
dans la classe Base
en public
et vous pouvez voir que maintenant vous pouvez accéder et appeler SomeClass.ThisWillBeCalledBeforeAnyMethodInChild code >
Ce n'est pas un héritage. C'est juste un accès.
les membres statiques sont hérités, mais ne peuvent pas être remplacés. comme les événements.
Donc, à part dans votre méthode enfant qui appelle base.MethodNameYouWantToCall () avant ou après, vous pouvez adopter une approche différente.
Ceci est juste une idée, et peut-être pas ce que vous essayez de réaliser, mais si j'avais besoin que chaque classe enfant appelle des fonctions parentes avant et après quelque chose, je pourrais faire ceci:
class Child : Parent { OtherCode { Console.Write("Hello world"); } }
class Parent { protected void Before() { /* does things */ } protected void After() { /* does things */ } abstract void OtherCode(); public void PubliclyExposedMethod { Before(); OtherCode(); After();' }
Dans ce qui précède, la méthode que vous définissez dans l'enfant sera exécuté après la méthode avant, et avant l'après. Je pense que c'est plus propre car cela réduit le nombre de fois où vous devez écrire base. ()
J'ai souvent vu cela, où OtherCode ()
s'appelle PubliclyExposedMethodCore ()
et est abstract
ou protected virtual code >.
Le nom commun de ce modèle est "méthode de modèle", au cas où vous voudriez en savoir plus. en.wikipedia.org/wiki/Template_method_pattern
avant
et après
n'a pas besoin d'être protégé
, seul OtherCode
doit être protégé code>. A part ça, bonne réponse.
Une idée qui me vient à l'esprit serait d'écrire une méthode wrapper qui obtient une action en paramètre. Là, vous pouvez appeler vos méthodes avant et après:
SomeClass.WrapperMethod(()=> SomeClass.SomeMethod1());
Vous l'appelleriez ainsi:
public class SomeClass : Base { public static void SomeMethod1() { //Do something } public static void SomeMethod2() { //Do something } public static void WrapperMethod(Action action) { Base.ThisWillBeCalledBeforeAnyMethodInChild(); action(); Base.ThisWillBeCalledAFTERAnyMethodInChild } }
Voici la réponse que vous attendiez: Non. Pas sans réécrire le code au moment de la compilation, ou générer des types de proxy au moment de l'exécution (par exemple les méthodes).
statique serait difficile à faire.