【问题标题】:How new keyword works in derive classnew 关键字在派生类中的工作原理
【发布时间】:2010-02-22 18:18:02
【问题描述】:

我对 new 关键字有些困惑,当我使用 virtual 和 override 时一切正常,但与 new 有点不同(我想我遗漏了一些东西)

 class A
{
    public virtual void Test()
    {
        Console.WriteLine("I am in A");
    }
}

class B:A
{
    public override void Test()
    {
        Console.WriteLine("I am in B");
    }
}


class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Test(); //I am in B
        A a = new B();
        Console.WriteLine(a.GetType()); // Type-B
        a.Test(); //I am in B
       Console.ReadKey();
    }
}

}

现在有了新的

class A
{
    public  void Test()
    {
        Console.WriteLine("I am in A");
    }
}

class B:A
{
    public new void Test()
    {
        Console.WriteLine("I am in B");
    }
}


class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Test(); //I am in B
        A a = new B();
        Console.WriteLine(a.GetType()); //B
        a.Test(); // I am in A ? why?
       Console.ReadKey();
    }
}

根据 MSDN 使用 new 关键字时,将调用新的类成员而不是已替换的基类成员。这些基类成员称为隐藏成员,GetType() 也将类型显示为 B。 所以我哪里出错了,这似乎是一个愚蠢的错误:-)

【问题讨论】:

    标签: c# new-operator shadowing


    【解决方案1】:

    当您使用 new 关键字隐藏基类方法时,调用由编译器解析,而不是在运行时解析。

    因此,当您编写 a.Test 时,编译器会发出对 A 类上的 Test 方法的调用。即使a 变量恰好引用了B 实例,编译器也不在乎,它仍然调用A 上的版本。

    当您调用虚拟方法时,编译器会发出callvirt 指令,告诉运行时根据实例的实际类型找到要调用的正确方法。运行时知道实例实际上是B 类型,并且会看到B 覆盖了该方法并调用了覆盖的版本。

    【讨论】:

    • 这意味着这是编译时间与运行时间。我明白你的意思,谢谢。
    【解决方案2】:

    查看Jon Skeet's description 的new 关键字用法。因为 a 被强制转换为 A,所以您正在调用 A 的方法,该方法不能被覆盖。 B 恰好有一个同名的方法。

    【讨论】:

      【解决方案3】:

      基本上,一旦您创建了派生自AB 的其他类,您会发现调用base.Test() 将调用A 的那些类的版本override 而不是@987654326 @ 以及从 B 派生的那些将调用 B 的版本,但不会调用 A 的版本。

      【讨论】:

        【解决方案4】:

        “新”表示该​​方法是“新的”而不是“覆盖”。因此,如果您从基类调用该名称的方法,它还没有被覆盖,因此不会调用派生类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-03
          • 1970-01-01
          • 2011-01-09
          • 2012-09-17
          • 2019-03-31
          • 1970-01-01
          • 2020-11-29
          相关资源
          最近更新 更多