At first sight, virtual dispatch might look like a bit of magic. The compiler did know about a static type, yet a virtual method override on the runtime type is considered for execution. How does that work? The answer lies in the runtime facilities provided for method calls. A set of different instructions exist to call methods, two of which are used by the C# compiler. One is
call, the other is
callvirt. From the name, you can already infer the task of the second (although the C# compiler uses it for other purposes too, as you will see).
Consider the following piece of code, given our
Circle classes we defined earlier. Observe how the call to
Radius involves a nonvirtual member, whereas the call to