在任何子方法之前(或之后)调用父方法

7

我很可能会在这里得到负面答案,但我想提出我的问题。

在C#中有没有一种方法可以在任何子类方法之前(或之后)调用父类方法。

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
    }
}

因此,我希望从基类中调用ThisWillBeCalledBeforeAnyMethodInChild方法,在SomeClassSomeMethod1SomeMethod2之前运行。类似的,也需要一个后置方法。

有没有不使用反射调用方法的方法来实现?


2
这是你期望的答案:不行。除非在编译时重写代码,或者在运行时生成代理类型(例如实例方法)。 - canton7
静态的话做起来会很困难。 - Daniel A. White
3个回答

4

除了在子方法中调用base.MethodNameYouWantToCall()的位置之外,在执行前或执行后,您可以采取不同的方法。

这只是一个想法,可能并不是您想要实现的内容,但如果我需要每个子类在某些操作之前和之后都调用父函数,我可能会这样做:

class Parent 
{ 
   protected void Before() { /* does things */ }
   protected void After() { /* does things */ }
   abstract void OtherCode();

   public void PubliclyExposedMethod {
        Before();
        OtherCode();
        After();'
}

class Child : Parent {
      OtherCode { Console.Write("Hello world"); }
}

在上述代码中,你在子类中定义的方法将在before方法之后、after方法之前执行。我认为这种方式更加清晰,因为它减少了编写base()的次数。

我经常见到这种情况,其中 OtherCode() 被称为 PubliclyExposedMethodCore(),并且是 abstract 或者 protected virtual - mmathis
1
这种模式的常见名称是“模板方法”,如果您想进一步了解它,请参阅以下链接:https://en.wikipedia.org/wiki/Template_method_pattern - Avner Shahar-Kashtan
beforeafter不需要被保护,只需保护OtherCode。除此之外,答案很好。 - Zohar Peled

1

我想到的一个想法是编写一个包装方法,将一个操作作为参数传入。在这里,您可以调用您的before和after方法:

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
    }

}

你会这样调用它:
SomeClass.WrapperMethod(()=> SomeClass.SomeMethod1());

0

首先,静态方法不参与继承。

您可以通过使用基指针来完全控制此过程,该指针是对此指针的基类的引用。

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();
    }
}

输出:

这之前 某个方法1 某个方法2 这之后


首先,静态方法不参与继承。你是怎么得出这个结论的呢?将Base类中的protected改为public,你会发现现在可以访问和调用SomeClass.ThisWillBeCalledBeforeAnyMethodInChild - Mong Zhu
那不是继承,那只是访问。 - matt-dot-net
静态成员可以被继承,但不能被重写。事件也是如此。 - Zohar Peled

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接