【问题标题】:Dynamic Binding in C#C# 中的动态绑定
【发布时间】:2012-06-01 15:46:44
【问题描述】:
class A 
 {
   public virtual void WhoAreYou() { Console.WriteLine("I am an A"); }
 }
class B : A
{
  public override void WhoAreYou() { Console.WriteLine("I am a B"); }
}
class C : B
{
 public new virtual void WhoAreYou() { Console.WriteLine("I am a C"); }
}
class D : C 
{
  public override void WhoAreYou() { Console.WriteLine("I am a D"); }
}


C c = new D();
c.WhoAreYou();// "I am a D"
A a = new D();
a.WhoAreYou();// "I am a B" !!!!

内部如何分配引用,引用A包含B的引用? 谁能解释一下发生了什么?

【问题讨论】:

  • 嗯,我可能错了,但我认为这就是正在发生的事情。当您声明 D 类的对象并将其分配给 C 类时 --- C 类有一个虚函数,在这种情况下,它只会使用 D 的覆盖函数。但是,当您声明 D 类的对象并将其分配给 A 类时,会发生什么,因为 D 从 C 继承,C 从 B 继承,B 最终从 A 继承,但同时覆盖 A,那么您就有了该 print 语句。跨度>
  • 怎么样:阅读 msdn 并尝试了解 virtual/override/new-machine?你的例子很清楚!
  • @Flo:在第一种情况下,对象 C 具有 D 的引用,它调用 D 的方法。但在第二种情况下,显然 A 具有 D 的引用,而方法调用它如何调用 B 的方法(内部发生的事情).. 安静混乱..
  • new virtual 在概念上是否有意义,您的预期结果是什么?
  • @Matthew : 明明隐藏基类实现,让派生覆盖。

标签: c# dynamic-binding


【解决方案1】:

C 类中,方法WhoAreYou() 不会覆盖基类方法,因为它是用new 关键字定义的,它添加了一个new 方法, 隐藏基类方法的名称。这就是为什么:

C c = new D();
c.WhoAreYou();// "I am a D"

调用D 中的重写方法,该方法重写了使用new 关键字定义的基类方法。

但是,当目标类型为A时,则:

A a = new D();
a.WhoAreYou();// "I am a B" !!!!

调用B 中被覆盖的方法,因为您正在调用a 类型为A 的方法,其方法被B 覆盖。

【讨论】:

  • 感谢纳瓦兹的回复。 A 有 D 的引用,A 不知道它的子类。所以,我必须从派生的一个开始跟踪。是这样吗?如果不是意味着.. 但是如果 D 的引用如何调用 B 的方法以及它如何跟踪来自 A 的派生类(在方法表方面)就像内部的东西一样会更好..
【解决方案2】:

您的 C 类 WhoAreYou() 方法是“新的”,因此对 B 隐藏了该方法。这意味着 D 类中的覆盖是覆盖 C 的方法而不是 B(覆盖 A)。

因为你有一个 A 的引用,它的 WhoAreYou() 函数的层次结构最底层是 B 类中的那个。

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

【讨论】:

    【解决方案3】:

    意思是C的

    public new virtual void WhoAreYou(){}
    

    打破虚方法链。

    当您通过引用 A 调用 D 的方法 WhoAreYou() 时,虚拟性开始工作,但在 C 处中断。

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多