using System;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
Animal a = new Cat();
Animal a1 = new Cat();
Animal b = new Dog();
Animal b1 = new Dog();
Animal c = new Mouse();
Animal c2 = new Mouse();
a.FindSamething(a1);
a.FindSamething(b);
a.FindSamething(c);
Console.WriteLine();
b.FindSamething(a);
b.FindSamething(b1);
b.FindSamething(c);
Console.WriteLine();
c.FindSamething(a);
c.FindSamething(b);
c.FindSamething(c2);
Console.WriteLine();
}
}
// 1. Cat, Dog 간 Double Dispatching 이 필요한 경우 구현 코드
partial class Animal
{
public virtual void FindSamething(Animal animal) => Console.WriteLine("Animal FindSamething");
public virtual void FindSamethingImpl(Cat obj) => Console.WriteLine("Animal-Cat FindSamethingImpl");
public virtual void FindSamethingImpl(Dog obj) => Console.WriteLine("Animal-Dog FindSamethingImpl");
}
partial class Cat : Animal
{
public override void FindSamething(Animal animal)
{
animal.FindSamethingImpl(this);
}
public override void FindSamethingImpl(Cat obj) => Console.WriteLine("Cat-Cat = Same");
public override void FindSamethingImpl(Dog obj) => Console.WriteLine("Cat-Dog = Cute");
}
partial class Dog : Animal
{
public override void FindSamething(Animal animal)
{
animal.FindSamethingImpl(this);
}
public override void FindSamethingImpl(Dog obj) => Console.WriteLine("Dog-Dog = Same");
// 이렇게 리다이렉션 하는 경우 호출객체와 인자가 뒤바뀌기 때문에
// this.FindSamethingImpl 와 obj.FindSamethingImpl 의 결과가 다른 경우에는 별도 구현해야함.
public override void FindSamethingImpl(Cat obj) => obj.FindSamethingImpl(this);
}
// 2. Mouse가 추가된 경우 추가 구현 코드
partial class Animal
{
public virtual void FindSamethingImpl(Mouse m) => Console.WriteLine("Animal-Mouse FindSamethingImpl");
}
partial class Cat
{
public override void FindSamethingImpl(Mouse m) => m.FindSamethingImpl(this);
}
partial class Dog
{
public override void FindSamethingImpl(Mouse m) => m.FindSamethingImpl(this);
}
partial class Mouse : Animal
{
public override void FindSamething(Animal animal)
{
animal.FindSamethingImpl(this);
}
public override void FindSamethingImpl(Cat c) => Console.WriteLine("Mouse-Cat = Mustache");
public override void FindSamethingImpl(Dog d) => Console.WriteLine("Mouse-Dog = Four Legs");
public override void FindSamethingImpl(Mouse m) => Console.WriteLine("Mouse-Mouse = Same");
}
}