Late Binding - Myths and Reality |
Written by Mike James | ||||||
Friday, 05 July 2024 | ||||||
Page 1 of 5 The accepted wisdom is that late binding is complicated and advanced. Not necesarily. Read on to find out how it’s easy in C# and how this illuminates what is going on in other languages.
The concepts of late and early binding can be confusing, mainly because they aren’t really as different as they might first seem. There is a sense in which late binding is really isn’t any different from early binding – you could say it’s more about the state of mind of the programmer, but it’s high time to look in more detail at how it all works. What is late about late binding?When you work with a strongly typed language then early binding is the norm – indeed it might even be the only type of binding allowed. The basic idea is that you declare the type of every variable you use within the code and this allows the compiler to check what you are writing for correctness. It can also allow the IDE to provide help by listing the methods and properties that you can use as in the Intellisense feature of Visual Studio or VS Code. Where early binding starts to show its limitations is when you need to write some code that deals with a range of data types. If at this point you are thinking “generics” then yes but it’s still, in concept, early bound. If you express an algorithm as generic code all that happens is that early binding is deferred until you specify, at design time, the types to be used with the template. That is when you actually use a generic you have to specify the type it is working with at design time. Late binding implies that the type of an object isn’t known until run time and this goes well beyond generic templates. To clarify what is going on It is useful to change from thinking about variables or instantiated classes to “pointers” or more properly references to instances. The reason is that if you think about variables it is easy to conclude that you need to know the type of an object when the variable is declared because otherwise how would the system know what memory to allocate to store the object. However if you have a pointer or a reference to an object the system doesn't need to know what it is referencing for practical purposes because a reference is a reference no matter what it references. References have to be typed not for any practical implementation reason but because a decision has been made to enforce early binding. This means that it is perfectly possible to have a pointer or reference to an instance of an unknown type – unknown that is at design time. To make use of the unknown type you have to discover its type at run time using some sort of dynamic type information. In .NET this dynamic type information is supplied by the “reflection” classes. In fact the reflection classes provide facilities that go beyond simple late binding to allow you to create types and instances dynamically. So the key idea in late binding is the use of a reference to an object whose type is only determined dynamically at run time. But wait! In reality all objects are managed using references, even if they are early bound, so the only real difference is the programmer’s ignorance and hence compiler's ignorance of the type at design time. This is a key observation – if the programmer knows the type then it’s early binding; if the programmer doesn’t know the type it’s late binding. Let’s see what happens if we pursue this idea. Late binding in actionSo much for theory; it’s time for an example, and examples are always better the simpler they are. In the real world late binding usually occurs in some messy, complicated, way that obscures what is happening. Let’s start with C#. In this case we need a class with a single method to try things out:
Now we are going to create and use an instance of the class but we are going to "pretend" not to know its type. As we don’t know its type we need an object variable to refer to the instance:
Clearly in this example the programmer does know the type of the instance stored in late at design time! This is even more obvious when you write the instantiation as:
The compiler also knows the type of “late” at design time but C# it does its best to ignore this - i.e. it doesn't apply any type inference. If you now write:
you will get a compile time error message which says that “object does not contain a definition for Method1” which is indeed true. It is in this sense that it is said that C# doesn’t support automatic late binding. The declared type of the reference to an object determines what methods and properties the object has irrespective of what methods and properties it actually has. This is enforced at design time by the compiler and it is what makes late binding seem impossible. But don’t give up on it just yet - dynamic types introduced in C# 4 make it easy.
|
||||||
Last Updated ( Friday, 05 July 2024 ) |