6
votes

Appeler une méthode parent avant (ou après) toute méthode enfant

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?


2 commentaires

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.


3 Réponses :


0
votes

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


3 commentaires

"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


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.



4
votes

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. ()


3 commentaires

J'ai souvent vu cela, où OtherCode () s'appelle PubliclyExposedMethodCore () et est abstract ou protected virtual .


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é . A part ça, bonne réponse.



1
votes

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
    }

}


0 commentaires