【问题标题】:Out-line for virtual method in C# [duplicate]C#中虚拟方法的大纲[重复]
【发布时间】:2016-10-22 13:51:36
【问题描述】:

我有一个 C# 代码示例

using System;
class A
{
  public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
  public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
  new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
   public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
static void Main() {
  D d = new D();
  A a = d;
  B b = d;
  C c = d;
  a.F();
  b.F();
  c.F();
  d.F();
}
}

这段代码大纲

B.F
B.F
D.F
D.F

我不明白为什么如果 a.F(); 有BF吗?

MS 如何说虚拟方法是由对象类型实时表示的

【问题讨论】:

    标签: c#


    【解决方案1】:

    在 a.F() 的情况下,存在 B.F,因为 A 类中的 virtual void F 在 B 中被覆盖。

    它不会被 C 覆盖,因为有一个 new 运算符不会覆盖虚拟基方法。

    因此,如果有一个类型为 D 的实例键入到 A 并且您调用 F(),则将调用类 A 中的虚拟方法,但会考虑最新的覆盖。那是B.F.

    【讨论】:

      【解决方案2】:

      从继承的类对象调用 F() 方法会为向下转换为类型 A 的 D 类型对象打印 B.F,因为您覆盖了 B 类(和 D 类)中的方法。

      您的测试与this MSDN post on virtual methods 中提供的示例几乎完全相同:

      using System;
      class A
      {
         public void F() { Console.WriteLine("A.F"); }
         public virtual void G() { Console.WriteLine("A.G"); }
      }
      class B: A
      {
         new public void F() { Console.WriteLine("B.F"); }
         public override void G() { Console.WriteLine("B.G"); }
      }
      class Test
      {
         static void Main() {
            B b = new B();
            A a = b;
            a.F();
            b.F();
            a.G();
            b.G();
         }
      }
      

      在示例中,A 引入了一个非虚方法 F 和一个虚 方法 G。B 类引入了一个新的非虚拟方法 F,因此 隐藏继承的F,也覆盖了继承的方法G。 示例产生输出:

      A.F
      B.F
      B.G
      B.G

      注意声明 a.G() 调用 B.G,而不是 A.G。这是因为 实例(即 B),而不是实例的编译时类型 (即 A),确定要调用的实际方法实现。 因为允许方法隐藏继承的方法,所以有可能 一个类包含多个具有相同的虚方法 签名。这并不存在模棱两可的问题,因为除了 最衍生的方法是隐藏的。在示例中

      【讨论】:

        【解决方案3】:

        我不明白为什么如果 a.F();有BF吗?

        MSDN #

        调用虚方法时,对象的运行时类型为 检查覆盖成员。最重要的成员 派生类被称为,它可能是原始成员,如果没有 派生类已覆盖该成员。

        粗体内容会告诉你为什么在调用A.F()时会打印B.F

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-15
          • 2017-08-13
          • 2016-04-12
          • 2012-09-21
          • 2015-09-09
          • 2019-01-01
          • 2014-08-13
          • 1970-01-01
          相关资源
          最近更新 更多