LA.NET [EN]

Oct 27

C# 4.0 introduced a new type whose main job is to simplify our job when writing code that needs to use reflection. I’m talking about the new dynamic type. As we all know, C# is type-safe programming language. In practice, this means that the compiler must resolve all expressions into types and their respective operations. Whenever the compiler detects an invalid operation (ex.: calling a method not exposed by a class), it must stop the compilation process and generate an error. The good news is that this type safety ensures that most (if not all) programmer’s errors are detected at compile time.

Compare this with what happens with other dynamic languages, like JavaScript. Before going on, a disclaimer: I love JavaScript, so any errors you might end up having while writing code in it can only be attributed to the developer writing it :,,) Anyway, how many times have we written JS code only to find out some misspelling error at runtime?

Now, there’s also advantages associated with dynamic languages. For instance, compare the code you need to write for using COM components from C# with the code you have to write to consume them from, say, JavaScript…yep, C# starts to suck when you need to do that. With the new dynamic type, things get better:) Here’s an example of what I mean:

dynamic word = new Application {Visible = true};
dynamic doc = word.Documents.Add(  );
word.Selection.TypeText( "Hello, dynamic!" );

Now, if you’re an experienced C# dev, you can’t stop noticing the simplicity of the new code. Just for the fun, let’s see the C# 3.0 equivalent code:

Application word = new Application{Visible = true};
//now, the fun begins
Object missingValue = Missing.Value;
Document doc = word.Documents.Add(
    ref missingValue, ref missingValue, ref missingValue, ref missingValue);
word.Selection.TypeText( "Hello, dynamic!" );

And I was lucky because I picked an easy method. If I needed to replace text, things would quickly become  even more boring…It’s safe to say that we all prefer version 1 of the previous example, right? And the good news is that you can use the same strategy when writing reflection code (for an example of it, check this old post).

So, what happens when you mark a variable or expression with the dynamic keyword? Whenever the compiler sees a dynamic expression, it will insert special code for describing that operation which is used at runtime to determine the real operation that needs to be performed.This special code is generated by the runtime binder. In C#, the runtime binder is defined in the Microsft.CSharp assembly and you must reference it whenever you use the dynamic keyword in your code.

At runtime, things get rather complicated because the binder ends up consuming more memory that would have been necessary if you’re using, say, reflection (if you’re using dynamic types only on a small portion of your code, then you probably should consider not using dynamic types since the advantages of dynamic might not pay off).

A dynamic operation is resolved at runtime according to the real type of the object. If that object implements the IDynamicMetaObjectProvider interface, its GetMetaObject method ends up being called. It returns a DynamicMetaObject derived type which is responsible for performing the bindings for members of that type (ie, mapping the members, methods and operators specified in the code you’ve written. Dynamic languages in .NET have their own DynamicMetaObject derived classes (which allows them to be easily consumed from C#). Something similar happens with COM components (the C# runtime binder uses a DynamicMetaObject derived object which knows how to communicate with COM components). When the object doesn’t implement the interface, C# ends up using reflection for executing the required operations.

Now, there are a couple of interesting operations you can do with a dynamic type. For starters, any expression can be implicitly converted into a dynamic type:

Int32 a = 10;
dynamic b = a;

Yep, you’ll end up with boxing in the previous snippet. Even more interesting is the fact that you can implicitly convert from a dynamic into some other type because the CLR will validate that cast at runtime:

Int32 c = a;

Notice that you cannot do this with an Object instance that resulted from boxing an integer. If the dynamic value isn’t compatible with the desired type, you’ll end up with a InvalidCastException. Another interesting thing is that evaluating a dynamic expression gives you a new dynamic expression:

dynamic a = 10;
Int32 b = 2;
var t = a + b;
t.DoesntHaveThisMethodButCompiles( );

You’ll succeed if you try to compile the previous snippet! Of course, you’ll get an exception at runtime since ints don’t have a DoesntHaveThisMethodButCompiles method. Notice that var is the same as dynamic in the previous snippet! (and, btw, don’t confuse var with dynamic. var is just a shortcut that lets the compiler infer the type of a variable).

Whenever you use a dynamic variable in a foreach or using block, the compiler will automatically generate the correct code for that scenario (in the foreach, it will convert the variable into an IEnumerable; in the using case, it will cast it to IDisposable). Pretty slick, right?

And that’s it. Stay tuned for more.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>