New features in C#4.0 (1)
The major theme for C# 4.0 is dynamic programming. Increasingly, objects are “dynamic” in the sense that their structure and behavior is not captured by a static type or at least not one that the compiler knows about when compiling your program. Some examples include:
a. objects from dynamic programming languages, such as Python or Ruby
b. ordinary .NET types accessed through reflection
c. objects with changing structure, such as HTML DOM objects
In order to clarify this, I copy a description about dynamic programming language from Wiki:
Dynamic programming language is a term used broadly in computer science to describe a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all.
C# 4.0 features a new dynamic keyword that allows you to mix in a bit of late-bound code in the midst of your otherwise statically typed code in an extensible way. This helps cleanup the string-based programming mess that is a characteristic of late-bound code.
The dynamic keyword can be used when declaring a variable, method return type, or parameter. It is used to declare that the static type of the thing is dynamic. When a variable is marked as being dynamic, C# won’t bother to resolve calls made on that object at compile-time: instead it will delay all method resolution to run time, but will use exactly the same algorithm as it would have used, so that overload resolution works correctly. Not only method calls, but also field and property accesses, indexer and operator calls and even delegate invocations can be dispatched dynamically.
At runtime a dynamic operation is dispatched according to the nature of its target object d:
If d is a COM object, the operation is dispatched dynamically through COM IDispatch. This allows calling to COM types that don’t have a Primary Interop Assembly (PIA) and relying on COM features that don’t have a counterpart in C #, such as indexed properties and default properties.
If d implements the interface IDynamicObject d itself is asked to perform the operation. Thus by implementing IDynamicObject a type can completely redefine the meaning of dynamic operations. This is used intensively by dynamic languages such as IronPython and IronRuby to implement their own dynamic object models. It will also be used by APIs, e.g. by the HTML DOM to allow direct access to the object’s properties using property syntax.
Otherwise d is a standard .NET object, and the operation will be dispatched using reflection on its type and a C# “runtime binder” which implements C#’s lookup and overload resolution semantics at runtime. This is essentially a part of the C# compiler running as a runtime component to “finish the work” on dynamic operations that was deferred by the static compiler.
Dynamic Language Runtime
An important component in the underlying implementation of dynamic lookup is the Dynamic Language Runtime (DLR), which is a new API in .NET 4.0. The DLR from Microsoft is an ongoing effort to bring a set of services that run on top of the CLR and provides and unifies language services for several different dynamic languages. These services include:
A dynamic type system, to be shared by all languages utilizing the DLR services.
a. Dynamic method dispatch
b. Dynamic code generation
c. Hosting API
The core of DLR includes Expression Trees, Dynamic Dispatch, and Call Site Caching. Expression Trees is introduced in LINQ; in C#4.0, it grows up to support statements. Dynamic Dispatch is about dispatching dynamic invocation to different binders, which allows us to communicate with different technologies. Call site caching is for efficiency. If the call is used many times, it just needs to do the resolution one time and cache the result then.
By having several dynamic language implementations share a common underlying system, it should be easier to let these implementations interact with one another. For example, it should be possible to use libraries from any dynamic language in any other dynamic language. In addition, the hosting API allows interoperability with statically typed .NET languages like C#. And the DLR will be used to implement dynamic languages like Python and Ruby on the .NET Framework. The DLR services are currently used in the development versions of IronRuby, a .NET implementation of the Ruby language, and the upcoming IronPython 2.0.
The basis of the dynamic resolution is the IDynamicObject interface, shared with the Dynamic Language Runtime. You can customize the dynamic process by implementing IDynamicObject interface, it can help you participate in the resolution of how method calls and property accesses are resolved. This has on it methods like Invoke which the compiler will call to allow the object itself to participate in method resolution. As well as allowing easy interaction with other dynamic languages such as IronPython and IronRuby this also has the benefit of making COM Interop much more natural. Rather than having to resort to Reflection, using dynamic typing will allow natural-looking code all the way.
public abstract class DynamicObject : IDynamicObject
public virtual object GetMember(GetMemberBinder info);
public virtual object SetMember(SetMemberBinder info, object value);
public virtual object DeleteMember(DeleteMemberBinder info);
public virtual object UnaryOperation(UnaryOperationBinder info);
public virtual object BinaryOperation(BinaryOperationBinder info, object arg);
public virtual object Convert(ConvertBinder info);
public virtual object Invoke(InvokeBinder info, object args);
public virtual object InvokeMember(InvokeMemberBinder info, object args);
public virtual object CreateInstance(CreateInstanceBinder info, object args);
public virtual object GetIndex(GetIndexBinder info, object indices);
public virtual object SetIndex(SetIndexBinder info, object indices, object value);
public virtual object DeleteIndex(DeleteIndexBinder info, object indices);
public MetaObject IDynamicObject.GetMetaObject();
var & dynamic
Please pay attention to the difference between var and dynamic. In C#3.0, there is a new keyword var. Local variables can be given an inferred "type" of var instead of an explicit type. The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET Framework class library.
But if the operand is dynamic, you can get the following benefits:
Member selection is deferred to run-time;
Actual type is substituted for dynamic at run-time;
Static result type of operation is dynamic.