1

我可以使用 base.virtualParentMethod() 调用父类方法。但是在以下场景中,如何在不创建它的对象的情况下调用父父类中的方法。

 class A
    {
        public virtual void virtualParentMethod()
        {
            Console.WriteLine("A");
        }
    }
    class B : A
    {
        public override void virtualParentMethod()
        {
            Console.WriteLine("B");
        }
    }
    class C : B
    {
        public override void virtualParentMethod()
        {
            //base.virtualParentMethod();
            //This is where I want to invoke the method of A
            //So that out Will be : A
        }
    }
4

5 回答 5

4

如果您需要一些父功能而不是父的直接子功能,那么您应该将该功能移至单独的方法:

class A
{
    public virtual void VirtualParentMethod()
    {
        Foo();
    }

    protected void Foo()
    {
        Console.WriteLine("A");
    }
}
class B : A
{
    public override void VirtualParentMethod()
    {
        Console.WriteLine("B");
    }
}
class C : B
{
    public override void VirtualParentMethod()
    {        
        Foo();
    }
}

更新

还要考虑:

  • 直接继承CA
  • 改变继承顺序,即BC
  • 将此行为提取到其他对象
于 2012-04-16T12:18:20.773 回答
2

您无法使用base语法选择要运行的派生方法的版本。运行特定方法的唯一方法是实例化可用于该方法的Ainside版本(基本上是 的真实实例)。CA

但是我个人不会这样做。这表明您的继承链存在设计问题。

如果您需要确保C运行A,为什么不AC- 继承C : A

于 2012-04-16T12:14:26.197 回答
0

您已经通过创建 C 的实例(如 C : B, B : A)创建了 A 的实例,因此有一种方法可以通过稍作修改来完成此操作。现在,没有说明这是否是一个好主意;

如果您在派生方法实现上使用“new”关键字而不是覆盖,那么您可以直接调用方法的基本实现,绕过中间类实现,通过将对象转换为您想要使用的实现类型,例如所以;

class A
{
    public virtual void virtualParentMethod()
    {
        Console.WriteLine("A");
    }
}
class B : A
{
    public new void virtualParentMethod()
    {
        Console.WriteLine("B");
    }
}
class C : B
{
    public new void virtualParentMethod()
    {
        // casting this to A will allow you to call the base class implementation
        ((A)this).virtualParentMethod();
    }
}

请注意,如果您进行此更改,则您已经为方法的任何调用者引入了行为更改,具体取决于它们引用对象的方式。如果您尝试在现有的 C.virtualParentMethod 实现中以这种方式进行转换(声明为“覆盖”),您实际上只是在调用该方法本身并将进入无限循环。

或者,您可以重新考虑您的课程设计。:-)

于 2012-04-18T23:51:07.530 回答
0

您根本不能,因为这是Virtual Method Table的本质,所以virtual关键字及其覆盖。调用方法的地址将从对应的实型虚拟方法表中查找。

于 2012-04-16T12:15:03.377 回答
0

你不能。使用 base.MethodName 将始终调用层次结构中最接近的实现,如果不明确声明可以调用的方法,就无法通过它

还值得注意的是,如果您发现自己处于希望这样做的情况,那么您就有设计缺陷。

于 2012-04-16T12:17:48.373 回答