If you don't mind creating a type map, you can fake a double dispatch as follows:
[EDIT] This new improved version is better suited for subclassing. If you have a class derived from another mammalian class (for example, Pug obtained from Dog in the example below), you do not need to explicitly add a feeder for the Pug class - it will automatically call the feeder for its base class, Dog .
But you can have a specific feeder for the derived class if you want, as evidenced by the Manx class below.
Using dynamic much easier! I just wanted to show how this might look if you are not using dynamic .
using System; using System.Collections.Generic; namespace Demo { public class Mammal {} public class Cat: Mammal {} public class Pig: Mammal {} public class Dog: Mammal {} public class Pug: Dog {} public class Manx: Cat {} public static class Feeder { static readonly Dictionary<Type, Action<Mammal>> map = createMap(); static Dictionary<Type, Action<Mammal>> createMap() { return new Dictionary<Type, Action<Mammal>> { {typeof(Cat), mammal => GiveFood((Cat) mammal)}, {typeof(Dog), mammal => GiveFood((Dog) mammal)}, {typeof(Manx), mammal => GiveFood((Manx) mammal)} }; } public static void GiveFood(Mammal mammal) { for ( var currentType = mammal.GetType(); typeof(Mammal).IsAssignableFrom(currentType); currentType = currentType.BaseType) { if (map.ContainsKey(currentType)) { map[currentType](mammal); return; } } DefaultGiveFood(mammal); } public static void DefaultGiveFood(Mammal mammal) { Console.WriteLine("Feeding an unknown mammal."); } public static void GiveFood(Cat cat) { Console.WriteLine("Feeding the cat."); } public static void GiveFood(Manx cat) { Console.WriteLine("Feeding the Manx cat."); } public static void GiveFood(Dog dog) { Console.WriteLine("Feeding the dog."); } } class Program { void test() { feed(new Cat()); feed(new Manx()); feed(new Dog()); feed(new Pug()); feed(new Pig()); feed(new Mammal()); } void feed(Mammal mammal) { Feeder.GiveFood(mammal); } static void Main() { new Program().test(); } } }
source share