Everything is early bound in C# unless you go through the Reflection interface.
Early bound just means the target method is found at compile time,
and code is created that will call this. Whether its virtual or not
(meaning there's an extra step to find it at call time is irrelevant).
If the method doesn't exist the compiler will fail to compile the code.
Late bound means the target method is looked up at run time. Often
the textual name of the method is used to look it up. If the method
isn't there, bang. The program will crash or go into some exception
handling scheme at run time.
Most script languages use late binding, and compiled languages use early binding.
C# (prior to version 4) doesn't late bind; they can however use the
reflection API to do it. That API compiles to code that looks up
function names by digging through assemblies at run time. VB can late
bind if Option Strict is turned off.
Binding usually has an effect on performance. Because late binding
requires lookups at runtime, it is usually means method calls are slower
than early bound method calls.
For a normal function, the compiler can work out the numeric location
of it in memory. Then it when the function is called it can generate an
instruction to call the function at this address.
For an object that has any virtual methods, the compiler will
generate a v-table. This is essentially an array that contains the
addresses of the virtual methods. Every object that has a virtual method
will contain a hidden member generated by the compiler that is the
address of the v-table. When a virtual function is called, the compiler
will work out what the position is of the appropriate method in the
v-table. It will then generate code to look in the objects v-table and
call the virtual method at this position.
So, there is a lookup that occurs for the virtual function. This is
heavily optimized so it will happen very quickly at run-time.
Early bound
- The compiler can work out where the called function will be at compile time.
- The compiler can guarantee early (before any of the programs code runs) that the function will exist and be callable at runtime.
- The compiler guarantees that the function takes the right number of
arguments and that they are of the correct type. It also checks that the
return value is of the correct type.
Late-binding
- The lookup will take longer because its not a simple offset calculation, there are usually text comparisons to be made.
- The target function may not exist.
- The target function may not accept the arguments passed to it, and may have a return value of the wrong type.
- With some implementations, the target method can actually change at
run-time. So, the lookup may execute a different function. I think this
happens in the Ruby language, you can define a new method on an object
while the program is running. Late-binding allows function calls to
start calling a new override for a method instead of calling the
existing base method.