new 关键字在派生类中如何工作

发布于 2024-08-23 01:52:19 字数 1142 浏览 8 评论 0原文

我对 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();
    }
}

}

new

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。 所以我出错的地方似乎是一个愚蠢的错误:-)

I am having some confusion with the new keyword,things work fine when I am using virtual and override , but a bit different with new(I think I am missing something)

 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();
    }
}

}

Now with new

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();
    }
}

as per MSDN When the new keyword is used, the new class members are called instead of the base class members that have been replaced. Those base class members are called hidden members, also the GetType() is Showing type as B.
So where I am going wrong, seems its a silly mistake :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

筱果果 2024-08-30 01:52:19

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

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

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

When you hide a base-class method using the new keyword, the call is resolved by the compiler, not at runtime.

Therefore, when you write a.Test, the compiler emits a call to the Test method on the A class. Even though the a variable happens to refer to a B instance, the compiler doesn't care, and it still calls the version on A.

When you call a virtual method, the compiler emits a callvirt instruction that tells the runtime to find the correct method to call based on the actual type of the instance. The runtime is aware that the instance is actually of type B, and will see that B overrides the method and call the overridden version.

海未深 2024-08-30 01:52:19

查看 Jon Skeet 的描述n new< /code> 关键字用法。因为 a 被强制转换为 A,所以您正在调用 A 的方法,该方法不能被重写。 B 恰好有一个同名的方法。

Check out Jon Skeet's description of the new keyword usage. Because a is cast as A, you are calling A's method, which cannot be overridden. B just happens to have a method with the same name.

挖个坑埋了你 2024-08-30 01:52:19

基本上,一旦您创建了从 AB 派生的其他类,您就会发现调用 base.Test() 将调用 <对于那些重写而不是new的类以及从B派生的类,code>A的版本将具有B 的版本被调用,但不是 A 的版本。

Basically, once you create additional classes which derive from either A or B, you'll find that calling base.Test() will call A's version for those classes which override rather than new and those which derive from B will have B's version called but NOT A's.

思念绕指尖 2024-08-30 01:52:19

“新”意味着该方法是“新”的,而不是“覆盖”的。因此,如果您从基类中调用该名称的方法,则该方法尚未被重写,因此不会调用派生类。

The "new" means the method is "new" and not an "override". Therefore, if you call a method by that name from the base, it hasn't been overriden so the derived won't be called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文