从基类调用子类的新方法

发布于 2024-08-23 02:27:28 字数 1216 浏览 2 评论 0原文

我有一些这样的类

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”。如何在不采用强制转换或通过覆盖更改方法声明的情况下获得与第一个示例相同的行为?

I've some classes like this

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

It works correctly, prints "METHOD FROM C"

BUT

if I've a situation like this

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

it prints "METHOD FROM A". How can I obtain the same behaviour of first example without adopt cast or change method declaration with override?

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

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

发布评论

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

评论(3

被翻牌 2024-08-30 02:27:28

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

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

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

你为什么要这样做?您实际上只是想重写尚未声明为虚拟的方法吗?如果是这样,那就没有办法解决这个问题——而且有充分的理由。如果作者在设计类时没有考虑到多态性,那么如果您能够重写该方法,它很容易就会崩溃。

当然,如果您将变量声明为子类的类型,如下所示:

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

那么调用新声明的方法。

You can't - this difference in behaviour is the whole point of using virtual/override.

When you declare a method with "new" you're saying "I know that I am hiding a method with the same signature rather than overriding it; I don't want polymorphic behaviour."

Likewise when you declare a method without specifying "virtual" you're saying "I don't want subclasses to be able to override this method."

Why do you want to do this? Are you actually just trying to override a method which hasn't been declared virtual? If so, there's no way round it - and for good reason. If the author hasn't designed the class with polymorphism in mind, it could easily break if you were able to override the method.

Of course, if you declare the variable to be of the type of the subclass, like this:

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

then that will invoke the newly declared method.

眉黛浅 2024-08-30 02:27:28

就像乔恩说的,避免它。但

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

        (a as C).method();

        Console.ReadLine();
    }

Like Jon said avoid it. But

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

        (a as C).method();

        Console.ReadLine();
    }
骄傲 2024-08-30 02:27:28

您可以使用dynamic关键字调用此方法。

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic 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");
        }
    }
}

you can use dynamic keyword call this method.

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic 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");
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文