The inheritance chain is as follows:
class A
{
public virtual void Foo()
{
Console.WriteLine(\"A\'s method\");
}
Amy's answer is correct. Here's how I like to look at this question.
A virtual method is a slot that can contain a method.
When asked to do overload resolution, the compiler determines which slot to use at compile time. But the runtime determines what method is actually in that slot.
Now with that in mind let's look at your example.
A has one slot for Foo. B has one slot for Foo, inherited
from A. C has two slots for Foo. One inherited from B, and
one new. You said you wanted a new slot named Foo, so you got it. D has two slots for Foo, inherited from C.That's the slots. So, what goes in those slots?
A, A.Foo goes in the slot.B, B.Foo goes in the slot.C, B.Foo goes in the first slot and C.Foo goes in the second slot. Remember, these slots are completely different. You said you wanted two slots with the same name, so that's what you got. If that's confusing, that's your problem. Don't do that if it hurts when you do it.D, B.Foo goes in the first slot and D.Foo goes in the second slot.So now what happens with your call?
The compiler reasons that you are calling Foo on something of compile time type A, so it finds the first (and only) Foo slot on A.
At runtime, the contents of that slot is B.Foo.
So that's what's called.
Make sense now?