方法重载和多态性

发布于 2024-10-16 08:38:36 字数 736 浏览 3 评论 0原文

class Program
    {
        static void Main(string[] args)
        {
            List<A> myList = new List<A> {new A(), new B(), new C()};

            foreach (var a in myList)
            {
                Render(a);
            }

            Console.ReadKey();
        }

        private static void Render(A o)
        {
            Console.Write("A");
        }

        private static void Render(B b)
        {
            Console.Write("B");
        }

        private static void Render(C c)
        {
            Console.Write("C");
        }
    }

    class A
    {

    }

    class B : A
    {

    }

    class C : A
    {

    }

输出为: AAA

是否可以以某种方式使用方法重载,以便输出为: ABC?

class Program
    {
        static void Main(string[] args)
        {
            List<A> myList = new List<A> {new A(), new B(), new C()};

            foreach (var a in myList)
            {
                Render(a);
            }

            Console.ReadKey();
        }

        private static void Render(A o)
        {
            Console.Write("A");
        }

        private static void Render(B b)
        {
            Console.Write("B");
        }

        private static void Render(C c)
        {
            Console.Write("C");
        }
    }

    class A
    {

    }

    class B : A
    {

    }

    class C : A
    {

    }

The output is: AAA

Is it possible to somehow use method overloading, so that the output would be: ABC?

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

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

发布评论

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

评论(4

傻比既视感 2024-10-23 08:38:36

如果您使用的是 C# 4,则可以使用动态类型:

foreach (dynamic a in myList)
{
    Render(a);
}

在静态类型中,重载决策在编译时执行,而不是在执行时执行。

对于在决策时选择的实现,您要么必须使用覆盖而不是重载,要么使用上面的动态类型。

You can use dynamic typing if you're using C# 4:

foreach (dynamic a in myList)
{
    Render(a);
}

Within static typing, overload resolution is performed at compile-time, not at execution time.

For the implementation to be chosen at decision time, you either have to use overriding instead of overloading, or use dynamic typing as above.

故乡的云 2024-10-23 08:38:36

以下应该可以解决问题,我们可以在使用该类型中的类型时控制行为:

class A
{
    public virtual void Render()
    {
        Console.WriteLine("A");
    }
}

class B : A
{
    public override void Render()
    {
        Console.WriteLine("B");
    }
}

class C : A
{
    public override void Render()
    {
        Console.WriteLine("C");
    }
}

static void Main(string[] args)
{
    var myList = new List<A> { new A(), new B(), new C() };
    foreach (var a in myList)
    {
        a.Render();
    }
    Console.ReadKey();
}

如果您希望类型的定义行为添加到其父级的行为中,则在之后调用基类中实现的方法执行你自己的逻辑,例如:

class B : A
{
    public override void Render()
    {
        Console.WriteLine("B");
        base.Render();
    }
}

The following ought to do the trick, where we control the behaviour when working with a type within that type:

class A
{
    public virtual void Render()
    {
        Console.WriteLine("A");
    }
}

class B : A
{
    public override void Render()
    {
        Console.WriteLine("B");
    }
}

class C : A
{
    public override void Render()
    {
        Console.WriteLine("C");
    }
}

static void Main(string[] args)
{
    var myList = new List<A> { new A(), new B(), new C() };
    foreach (var a in myList)
    {
        a.Render();
    }
    Console.ReadKey();
}

And if you want the defined behaviour of a type to be additive to that of its parent, then call the method implemented in the base after executing your own logic, for example:

class B : A
{
    public override void Render()
    {
        Console.WriteLine("B");
        base.Render();
    }
}
记忆里有你的影子 2024-10-23 08:38:36

实现此目的的另一种方法是使用访问者模式:它允许您实现类似的目标 使用双向方法调用系统的多态性:

interface IRenderable
{
    AcceptForRender(Program renderer);
}

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        var myList = new List<IRenderable> {new A(), new B(), new C()};

        foreach (var a in myList)
        {
            a.AcceptForRender(p);
        }

        Console.ReadKey();
    }

    public void Render(A o)
    {
        Console.Write("A");
    }

    public void Render(B b)
    {
        Console.Write("B");
    }

    public void Render(C c)
    {
        Console.Write("C");
    }
}

class A : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

class B : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

class C : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

这种方法的优点是可以有效地实现多态性(每种类型通过传递强类型的 this 内部渲染),同时保留不属于您的类型本身的逻辑(例如,视觉渲染逻辑)。

Another way to accomplish this is with the visitor pattern: it allows you to achieve something like polymorphism using a two-way method calling system:

interface IRenderable
{
    AcceptForRender(Program renderer);
}

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        var myList = new List<IRenderable> {new A(), new B(), new C()};

        foreach (var a in myList)
        {
            a.AcceptForRender(p);
        }

        Console.ReadKey();
    }

    public void Render(A o)
    {
        Console.Write("A");
    }

    public void Render(B b)
    {
        Console.Write("B");
    }

    public void Render(C c)
    {
        Console.Write("C");
    }
}

class A : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

class B : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

class C : IRenderable
{
    public void AcceptForRender(Program renderer)
    {
        renderer.Render(this);
    }
}

The advantage to this approach is that it allows you to effectively achieve polymorphism (each type ensures the correct overload is called by passing the strongly-typed this to Render internally) while keeping logic that does not belong in your types themselves (e.g., visual rendering logic) out.

神回复 2024-10-23 08:38:36

使 ABC 派生自基(抽象)类,在该类中定义方法 Render 并在每个 ABC 中正确重写。不要先调用 Render(a),然后再调用 a.Render(),这才是多态性的工作方式。

Make A B C deriving from a base ( abstract ) class, define in that class a method Render and override properly in each A B C . Instead of calling Render(a) then call a.Render() this is the way polymorfism is supposed to work.

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