A different kind of runtime polymorphism
Let’s start with toy problem: you have a basket which contains fruits and you want to iterate over all the fruits and do something different with each type of fruit.
A trivial implementation looks something like this:
class Fruit
{
public virtual Eat()
{
Console.WriteLine("Eating some unknown fruit");
}
}
class Apple : Fruit
{
public override Eat()
{
Console.WriteLine("Eating an apple");
}
}
class Orange : Fruit
{
public virtual Eat()
{
Console.WriteLine("Eating an orange");
}
}
class Program
{
static void Main(string[] args)
{
List<Fruit> basket = new List<Fruit>();
basket.Add(new Apple());
basket.Add(new Orange());
basket.ForEach(f => f.Eat());
}
}
This is great when you control the Fruit
class hierarchy.
What can you do when the Fruit
hierarchy is out of your control? And it has no Eat
method?
You could try overloads
class Program
{
static void Main(string[] args)
{
List<Fruit> basket = new List<Fruit>();
basket.Add(new Apple());
basket.Add(new Orange());
basket.ForEach(Eat);
}
static void Eat(Fruit fruit)
{
Console.WriteLine("Eating some unknown fruit");
}
static void Eat(Apple apple)
{
Console.WriteLine("Eating an apple");
}
static void Eat(Orange orange)
{
Console.WriteLine("Eating an orange");
}
}
unfortunately it will just call the Fruit
kind of overload:
Eating some unknown fruit Eating some unknown fruit
dynamic
to the rescue:
basket.ForEach(fruit => Eat((dynamic)fruit);
results in
Eating an apple Eating an orange
What is going on here?