如何在不创建父对象的情况下调用父类方法

时间:2012-04-16 12:11:03

标签: c# .net oop

我可以使用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
        }
    }

5 个答案:

答案 0 :(得分: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();
    }
}

更新

还要考虑:

  • 直接从C
  • 继承A
  • 更改继承顺序,即B
  • 中的C
  • 将此行为提取到其他对象

答案 1 :(得分:2)

您无法使用base语法选择要运行的派生方法的版本。运行特定方法的唯一方法是在A内实例化可用于该方法的C版本(基本上,{{1>真实实例{{1} }})。

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

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

答案 2 :(得分:0)

你根本不能,因为这是Virtual Method Table的本质,所以virtual关键字及其覆盖。 Invokation方法的地址将从相应的 real 类型虚拟方法表中查找。

答案 3 :(得分:0)

你做不到。使用base.MethodName将始终调用最接近的层次结构,并且没有办法在没有明确声明可以调用的方法的情况下传递它

值得注意的是,如果你发现自己处于这样的情况,那么你就有可能遇到设计缺陷。

答案 4 :(得分:0)

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

如果在派生方法实现上使用'new'关键字而不是override,那么可以通过将对象转换为您想要的类型实现来绕过中间类实现,直接调用方法的基本实现。使用,像这样;

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实现(声明为'override')中以这种方式进行转换,那么你实际上只是调用方法本身并且将进入无限循环。

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