tags:

views:

3985

answers:

6

I'm trying to get my head around when early/late binding occurs in C#.

Non-virtual methods are always early bound. Virtual methods are always late bound: the compiler inserts extra code to resolve the actual method to bind to at execution time and checks for type safety. So subtype polymorphism uses late binding.

Calling methods using reflection is an example of late binding. We write the code to achieve this as opposed to the compiler. (E.g. calling COM components.)

VB.NET supports implicit late binding when Option Strict is off. An object is late bound when it is assigned to a variable declared to be of type Object. The VB compiler inserts code to bind to the right method at execution time and to catch invalid calls. C# does not support this feature.

Am I heading in the right direction?

What about calling delegates and calling a method through an interface reference? Is that early or late binding?

Thanks,

A confused newbie

+17  A: 

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.
Scott Langham
I think you meant to say "The VB language itself doesn't late bind..."
Michael Meadows
Actually, I don't use VB... so I don't know a lot about that. I did mean C#, but it looks like I was just repeating myself. I would imagine though that you're correct, so I'll fix it up!
Scott Langham
With the dynamic keyword, late binding will be available in C# 4.
configurator
Dynamic typing is not the same as late binding. The difference is subtle, but it's important. Late binding still binds to a type, it just does it at runtime. Dynamic typing does not bind; instead, it resolves member information at runtime irrespective of type.
Michael Meadows
Thanks for the above comment, didn't know that
vdhant
Late binding doesn't bind to a type. The variable is declared without a type and the method is resolved by name at runtime irrespective of type.
Jonathan Allen
+3  A: 

C# 3 uses early binding.

C# 4 adds late binding with the "dynamic" keyword. See Chris Burrow's blog entry on the subject for details.

As for virtual versus non-virtual methods, this is a different issue. If I call string.ToString(), the C# code is bound to the virtual object.ToString() method. The code of the caller does not change based on the type of the object. Rather, virtual methods are called through a table of function pointers. An instance of object refers to object's table pointing at it's ToString() method. An instance of string has it's virtual method table pointing at it's ToString() method. Yes, this is polymorphism. but it is not late binding.

Joe Erickson
A: 

Scott: Thanks for your reply. But I'm still confused.

You say "Early bound just means the target method is found at compile time". For a virtual method how can the target method be found at compile time? Given that the compiler may not be able to determine whether a reference is pointing to an instance of a base type or a derived type, the compiler can't "find" and thus hard-code the call to a particular method at compile time. It must insert code to "find" the method at execution time. That is late binding, surely?. It's how subtype polymorphism is implemented, isn't it? (I seem to remember reading that .NET uses the IL instruction callvirt for late binding.)

...and C# defaults to early binding, as by default methods are non-virtual, whilst Java defaults to late binding as in Java methods are virtual by default. ???

Josh

Because the binding is done and known at compile time. It won't go to a particular address. It goes to an element in a vtable that points to the method to call.In C# when I call a virtual method on an object it will always be the same virtual method.In late binding, that method could change.
plinth
I added a bit more to my answer. I guess the main point is with early-binding the compiler can guarantee the call will succeed, with late-binding it can't.
Scott Langham
Plinth's point is good.
Scott Langham
A: 

So, as is often the case, it's all down to the precise meaning of the terms early binding and late binding.

You said:

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.

This, as I have always understood it, is early binding. (The C language only has this type of binding.)

You then said:

For an object that has any virtual methods, ...

This is late binding. The compiler is introducing mechanisms so as to be able to execute different method bodies as determined by the actual type of object (within the inheritance chain) that it comes across at execution time. See for example Heller, Roberts. Complete Java 2 Certification Study Guide. John Wiley & Sons; 5th Edition, 2005 or Eckel, Allison. Thinking in C++. Prentice Hall; 2004.

From what you say, both my definitions of early and late binding are what in the .NET world is known as early binding. The compiler knows there is an appropriate method body and links to it directly, or for virtual methods indirectly through the v-table mechanism.

In late binding on the other hand, the link to the method is made at execution time. In essence, the object is interrogated to determine if the method exists and if so it is called; otherwise we get a run-time error.

Josh

You may consider that even with a normal function it will be given a location in the processes virtual memory space. But, the operating system maps this to physical memory. So a translation is occuring at runtime to find where the function really is in physical memory. This is pretty similar to the
Scott Langham
virtual function where a translation happens at run-time. Also, some compilers are smart enough to realize that possible program flows mean some virtual function calls will always result in the same exact function being called. They can optimize this away so that it behaves the same as a normal call
Scott Langham
I think the decider of early or late bound is whether or not a function call can be correctly bound at compile time or run-time. I don't think binding requires knowing the exact single function that will be called and where it will be located.
Scott Langham
Binding just requires verification that a suitable function is available. Dispatching is the term used for dealing with how a suitable function is actually located and called at run-time. With early binding, some of the dispatching calculation can usually be performed at compile as an optimization
Scott Langham
A: 

Michael: I've just read your comment to Scott's answer. Would you care to elaborate as to precisely what you mean by "Late binding still binds to a type, it just does it at runtime" and "Dynamic typing does not bind; instead, it resolves member information at runtime irrespective of type."

What are the mechanisms involved in these two cases?

Thanks again everyone, the mist is lifting slowly...

Josh.

A: 

This article is a guide to building a .net component ,using it in a Vb6 project at runtime using late binding, attaching it's events and get a callback.

http://www.codeproject.com/KB/cs/csapivb6callback2.aspx

csexpert