方法重载和多态

sve*_*vit 11 .net c# polymorphism overloading

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
    {

    }
Run Code Online (Sandbox Code Playgroud)

输出为:AAA

是否有可能以某种方式使用方法重载,因此输出将是:ABC?

Jon*_*eet 14

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

foreach (dynamic a in myList)
{
    Render(a);
}
Run Code Online (Sandbox Code Playgroud)

在静态类型中,重载解析在编译时执行,而不是在执行时执行.

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


Gra*_*mas 14

以下应该做的伎俩,我们在使用该类型的类型时控制行为:

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();
}
Run Code Online (Sandbox Code Playgroud)

如果您希望类型的已定义行为与其父类的行为相加,则在执行您自己的逻辑后调用基础中实现的方法,例如:

class B : A
{
    public override void Render()
    {
        Console.WriteLine("B");
        base.Render();
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*Tao 6

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是它允许您有效地实现多态性(每种类型通过将强类型传递thisRender内部来确保正确的重载),同时保持不属于您的类型的逻辑(例如,可视化呈现逻辑)出.