c# - 从基类调用子类的新方法

标签 c# methods new-operator invoke base-class

我有一些这样的类(class)

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public virtual void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public override void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

它工作正常,打印“METHOD FROM C”

但是

如果我遇到这样的情况

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public new void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

它打印“METHOD FROM A”。如何在不采用强制转换或使用覆盖更改方法声明的情况下获得与第一个示例相同的行为?

最佳答案

你不能 - 这种行为上的差异是使用虚拟/覆盖的全部意义。

当您使用“new”声明一个方法时,您是在说“我知道我正在隐藏一个具有相同签名的方法而不是覆盖它;我不想要多态行为。”

同样,当您声明一个方法但未指定“虚拟”时,您是在说“我不希望子类能够覆盖此方法。”

你为什么要这样做?您实际上只是在尝试覆盖尚未声明为虚拟的方法吗?如果是这样,就没有办法绕过它 - 这是有充分理由的。如果作者在设计类时没有考虑到多态性,那么如果您能够覆盖该方法,它很容易崩溃。

当然,如果声明变量是子类的类型,像这样:

C c = new C();
c.method();

然后调用新声明的方法。

关于c# - 从基类调用子类的新方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2362354/

相关文章:

c++ - 在大块中进行分页时,堆分配是否更有效?

c++ - new(size) 和 new[size] 的区别

c# - 我怎样才能删除最后一部分?

c# - Azure根据上次修改删除旧的blob

java - Java 8 中字符串到方法的映射,传递参数

c# - 在重载方法上使用泛型参数

c# - 名称不能以 '1' 字符开头,十六进制值为 0x31。从 xml 文件读取时

javascript - Asp.net RegisterStartupScript 未触发

ruby - 如何在 Ruby 的子模块中正确封装方法?我的方法不会出现在任何地方!

c++ - 为什么 operator new 函数需要转换