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?
答案 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()
这是多态性应该工作的方式。