C# .NET Framework 4 – Adds Dynamic Binding & Dynamic Object
With dynamic binding, when you have an object in your hand, you do not need to worry about whether it comes from COM, IronPython, the HTML DOM, reflection or elsewhere; you just apply operations to it and leave it to the runtime to figure out what exactly those operations mean for that particular object.
This affords you enormous flexibility, and can greatly simplify your code, but it does come with a significant drawback: Static typing is not enforced for these operations. A dynamic object is assumed at compile time to support any operation, and only at runtime will you get an error if it wasn’t so.
The dynamic type
C# 4.0 has introduced a new static type called dynamic. When you have an object of type dynamic you can “do things to it” that are resolved only at runtime. This is similar to the object notation in PowerBuilder where you might use the object notation to reference the HTML DOM via a browser control or call a BAPI in SAP. If you have done any of this in PowerBuilder you are aware of how inflexible the virtual machine can be when it comes to resolving dynamic types, and how important it is to catch exceptions. C# in general is much more forgiving in my experience when working with dynamic types.
Another subject but worth mentioning is the new support for optional parameters and named arguments which are not available in PowerBuilder as of version 11.5.
Dynamic type in C# (4.0)
dynamic d = GetDynamicObject(…);
The C# compiler allows you to call a method with any name and any arguments on d because it is of type dynamic. At runtime the actual object that d refers to will be examined to determine what it means to “call M with an int” on it.
The type dynamic can be thought of as a special version of the type object, which signals that the object can be used dynamically. It is easy to opt in or out of dynamic behavior: any object can be implicitly converted to dynamic, “suspending belief” until runtime. Conversely, expressions of type dynamic can be implicitly converted to object, or any other type, as long as a conversion exists at runtime:
dynamic d = 7; // compile-time implicit conversion
int i = d; // runtime implicit conversion
Not only method calls, but also field and property accesses, indexer and operator calls and even delegate invocations and constructor calls can be dispatched dynamically:
dynamic d = GetDynamicObject(…);
d.M(7); // calling methods
d.f = d.P; // getting and settings fields and properties
d[“one”] = d[“two”]; // getting and setting through indexers
int i = d + 3; // calling operators
string s = d(5,7); // invoking as a delegate
var c = new C(d); // calling a constructor
The role of the C# compiler here is simply to package up the necessary information about “what is being done to d”, so that the runtime can pick it up and determine what the exact meaning of it is given an actual object d. Think of it as deferring part of the compiler’s job to runtime.
The result of any dynamic operation is itself of type dynamic, with two exceptions:
- The type of a dynamic constructor call is the constructed type
- The type of a dynamic implicit or explicit conversion is the target type of the conversion.
At runtime a dynamic operation is dispatched according to the nature of its target object d:
Have you seen the movie “Inception“? For some reason I think of it when thinking of this… if d implements the interface IDynamicMetaObjectProvider, it is a so-called dynamic object, which means that it will itself be asked to bind and perform the operation. Thus by implementing IDynamicMetaObjectProvider a type can completely redefine the meaning of operations such as method calls, member access etc.! This is pretty cool stuff and supports good object oriented design, it is already used intensively by dynamic languages such as IronPython and IronRuby. It is also used by APIs, e.g. by the Silverlight HTML DOM to allow direct access to the object’s properties and methods using member access and method call syntax instead of string-based accessor methods such as SetProperty or Invoke.
So the addition of Dynamic Binding and Dynamic Objects adds a lot of power and flexibility to the already robust C# language. Named and Optional Arguments are icing on the cake. And I’m finally getting a handle on Linq, let me say this… Linq is HUGE, Microsoft hit a grand-slam home run with Linq. I’ll save that for another article.
DisplacedGuy (aka Rich Bianco)