When you are writing code and your variable types don't matter, you are practicing type-less programming. This is true of Variants in VB6, in languages like Visual FoxPro, and of the type system in functional programming languages such as LISP.
Type-less programming, often called "late binding," is all about flexibility. It's perfect for building quick prototypes or function stubs when the final details, such as return types and parameter types, haven't been decided. When designing VB.NET, one of the goals was to continue to support type-less programming in similar fashion to VB6. Type-less programming has the huge effect of making all versions of Visual Basic a rapid prototyping tool.
The switch that controls this type-less programming behavior is Option Strict. With Option Strict off (the default), an Object can be used as a general type. With Option Strict on, the developer must explicitly specify the type of each expression. This may involve adding CTypes, or conversion expressions, in key places or changing the types of variables. Aside from simple conversions, type-less programming also entails late binding.
When compiling a piece of source code, the compiler must decide what each identifier represents. This process is called binding because it "binds" the string of characters to an actual method or member of a class. Here's an example:
Dim cls As Class1 = New Class1()
Dim obj As Object = New Class1()
cls.Print 'call determined at compile time
obj.Print 'call determined at run time
When analyzing the text "cls.Print," the compiler first determines what type "cls" refers to, which is Class1
. Then it takes the string "Print" and looks in Class1
for a member called Print
. If Class1
contains such a member, then "cls.Print" has been successfully bound, and the intermediate language (IL) for this expression can be emitted. If not, the compiler generates an error that Print
is not a member of Class1
Most of this binding work occurs at compile time; the compiler has determined exactly what members to call by the time it creates an .EXE or .DLL. Sometimes, however, this information is impossible to determine until the program actually runs, so the compiler defers binding until run time. The process of binding deferral is called late binding. You're most likely doing late binding anytime you use "." on an Object variable. Late binding can also be thought of as type-less programming because type constraints are considered only at runtime.
When analyzing the text "obj.Print" from the code above, the compiler determines that obj
is an Object variable. Depending on how the program runs, obj
can hold an instance of any type.
Because of this, the compiler has to treat obj.Print
as a late bound call and wait until run time to determine what it does. The mechanism that determines what to call at run time is called the VB Late Binder. If you were to analyze the IL that the compiler generates for the obj.Print
call, you would see that the compiler is, metaphorically speaking, sending a message to the VB Late Binder which says, "You need to perform a call to Print
and here is all the information I have." The VB Late Binder, contained within Microsoft.VisualBasic.dll and written entirely in Visual Basic, looks at the type contained in obj
and tries to find a member called Print
. If it succeeds, it makes the call. If it fails, the VB runtime throws a MissingMember exception.
You can also dynamically load .NET assemblies and easily use their containing types without having to deal with the complexities of reflection and method invocation. This code snippet dynamically loads an assembly called WidgetLibrary
and instantiates an object of type Widget
Dim lib = [Assembly].Load("WidgetLibrary")
Dim obj = lib.CreateInstance("Widget")
The beauty here is that you can use Widget
just as you would any other type, except the compiler knows nothing about it when it builds the .EXE. All the method binding is performed at run time on an as-needed basis.
Keep in mind that this flexibility comes at a sacrifice of some performance. But when you need to get a project off the ground as quickly as possible, late binding can be just the right catalyst. (See Sidebar: Control Anchoring