方法重载和多态

时间:2011-02-07 13:09:46

标签: c# .net 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
    {

    }

输出为:AAA

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

4 个答案:

答案 0 :(得分:14)

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

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

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

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

答案 1 :(得分: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();
}

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

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

答案 2 :(得分:6)

另一种实现此目的的方法是使用visitor pattern:它允许您使用双向方法调用系统来实现多态性:

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传递给Render来确保正确的重载),同时保持逻辑不属于您自己的类型(例如,视觉呈现逻辑)。

答案 3 :(得分:2)

使A B C从基础(抽象)类派生,在该类中定义一个方法在每个A B C中正确渲染和覆盖。而不是调用Render(a)然后调用a.Render()这是多态性应该工作的方式。