Late Binding - Myths and Reality
Written by Mike James   
Friday, 05 July 2024
Article Index
Late Binding - Myths and Reality
Dynamic C#
Inheritance and Conditional Casting
Real late binding

Inheritance and Conditional Casting

You may still not be happy with the example because in practice late binding is usually associated with a hierarchy of classes rather than a mutually exclusive choice between a small number of incompatible classes.

For example, if we change Class2 to be:

class Class2:Class1

Class2 now has a Method1 member and, from the point of calling Method1, it doesn’t matter if we treat Class2 as itself or as an example of Class1. For example:

if (late is Class1){
 int count = ((Class1)late).Method1("Hello World");

results in Method1 being called irrespective of whether or not late is Class1 or Class2. The reason is that the “is” operator returns true if late is of type Class1 or can be safely cast to Class1.

There is the small matter of polymorphism to consider in all of this.

For example, if Class2 overrides Method 1 as:

public new int  Method1(string text) {
 return 2 * text.Length;

i.e. returning twice the length of the string, then which method you call for a Class2 object depends on whether you treat it as a Class1 object when you get the original method or a Class2 object when you get the new method. That is it matters what type you cast the object to.

In other words if late is a reference to a  Class2 object:

int count = ((Class1)late).Method1("Hello");

calls the method defined in Class1 and if you use:

int count = ((Class2)late).Method1("Hello");

this calls the method in defined in Class2.

Also notice that the result of the cast isn't changed if Method1 is virtual and overriden in Class2. The difference between virtual and non-virtual only changes which method is called when the referencing variable type is Class1 and the object referenced is Class2.

That is if late is a reference to a Class2 object then what you get when you write:

Class1 temp = (Class2)late;
int count=temp.Method1("Hello");

depends on how Method1 is declared. If it is non-virtual then the call to Method1 uses Class1's definition even thought the object is of type Class2.

For non-virtual methods the method called depends on the design time type of temp. However if Method1 is virtual in Class1 and overridden in Class2 then it is Class2's version of the method that is called. That is for virtual methods the method called depends on the runtime type of the object referenced by temp.

And yes this is complicated as the behaviour all depends on whether or not you assign your cast to another variable.

If you use dynamic for the late reference then the behaviour is more or less the same. Which method you call is determined by the runtime type of the instance. That is:

dynamic late;

results in Class1's Method1 being used if late is a reference to a Class1 object and to Class2's Method1 if it is a reference to a Class2 object. The casts are implied and once again virtual/non-virtual makes no difference unless you assign the cast to another variable before using it.



Last Updated ( Friday, 05 July 2024 )