在该方法的覆盖中调用基本抽象方法

时间:2011-04-12 15:42:16

标签: c#

如果我有以下内容:

e.g。

public abstract class ClassA
{
     protected abstract void ValidateTransaction();
}

public abstract class ClassB : ClassA
{
     protected override void ValidateTransaction()
     {
          // some custom logic here
     }
}

public class ClassC : ClassB
{
     protected override void ValidateTransaction()
     {
          base.ValidateTransaction();
          // some additional custom logic here
     }
}

所以我没有在ClassC的ValidateTransaction上找到用法。我没有看到它在任何地方被调用。

那么我想这是怎么回事?我的意思是它在这里调用堆栈顶部的方法(调用ClassB的覆盖方法,然后在ClassC的ClassB的方法中包含逻辑?)

这对我来说没有意义,为什么或如何运作或这里的意图。

已更新

好的,所以我找到了一个地方,从我们项目中的很多子类调用ClassA的PerformTransaction()方法。

所以ClassA现在看起来像这样,在这里有更多细节:

public abstract class ClassA
{
     public void PerformTransaction()
     {
           ValidateTransaction();
           // and calls some other code here.
     }

     protected abstract void ValidateTransaction();
}

好的,我们仍然有:

public abstract class ClassB : ClassA
{
     protected override void ValidateTransaction()
     {
          // some custom logic here
     }
}

public class ClassC : ClassB
{
     protected override void ValidateTransaction()
     {
          base.ValidateTransaction();
          // some additional custom logic here
     }
}


public class SomeAbritraryClass : ClassC
{
      ClassA.PerformTransaction();
      ...
 }

所以在一些继承ClassC的类中调用了ClassA.PerformTransaction()。

3 个答案:

答案 0 :(得分:2)

好吧,它调用了ClassC的覆盖方法......这恰好调用了ClassB的实现。它不是直接在ClassC的编译代码中“包含”ClassB的实现逻辑,或类似的东西 - 它只是另一种方法调用。

目前还不完全清楚是什么令你感到困惑 - 行为,设计意图或Find Usages向您展示的内容。

请注意,尽管有主题行,但您调用“基本抽象方法” - 您正在调用该方法的实现。编译器知道ClassC派生自ClassB,ClassB提供了该方法的实现,因此它明确地进行了调用。你不能从ClassB本身做同样的事情,因为那时base.ValidateTransaction真的试图调用一个抽象的基本方法。

有趣的事实:尽管调用了一个虚方法,但它是一个非虚方法调用:编译器知道要使用的确切实现,并将其加入调用。如果它虚拟调用,那么你最终会回到ClassC实现中,因为它会覆盖它:)

答案 1 :(得分:0)

  

那么我想这是怎么回事?我的意思是它在这里调用堆栈顶部的方法(调用ClassB的覆盖方法,然后在ClassC的ClassB的方法中包含逻辑?)

是的,基本上就是这样。当您在ValidateTransaction的实例上调用ClassC时,会运行该方法。然后,它显式执行基类(ClassB)方法,然后添加自己的附加验证。

您可能找不到ClassB.ValidateTransaction()直接用法,因为没有ClassB(定义为ClassB)的实例。但是,任何ClassC来电都会通过ClassB.ValidateTransaction()行间接使用base.ValidateTransaction()

答案 2 :(得分:0)

当调用C类覆盖时,它将首先调用B的覆盖并在那里执行一些逻辑,然后由C的逻辑扩展。

我知道他们可以使用相同的变量数据。我不知道,因为我没有所有的数据。