Imagine you have an object Item and another object
StackableItem : Item, that inherits from Item. Now imagine I have an array of Items. I can put Stackable items in here and I can put items in here, no problem. But when I come to use the array I don't know which are items and which are stackable items. To find out which are which I might use a dynamic cast, or in C# you can use method overloading and the program will do the dynamic cast for you (I assume it does that anyway).
public void AddItem(Item item)
Console.WriteLine("Not so clever");
/// Is C# clever enough to go to the correct one?
/// <param name="item"></param>
public void AddItem(StackableItem item)
So in the above if I have:
Item i = new StackableItem();
The second function will be called. Neat right? Yes, yes it is.