我可以使用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
}
}
答案 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')中以这种方式进行转换,那么你实际上只是调用方法本身并且将进入无限循环。
或者,您可以重新考虑您的课程设计。 : - )