Free mag vol1 | Page 664

CHAPTER 16  DYNAMIC TYPES AND THE DYNAMIC LANGUAGE RUNTIME The Role of the Dynamic Language Runtime (DLR) Now that you better understand what “dynamic data” is all about, let’s learn how it is processed. With the release of .NET 4.0, the Common Language Runtime (CLR) was supplemented with a complementary runtime environment named the Dynamic Language Runtime (DLR). The concept of a “dynamic runtime” is certainly not new. In fact, many programming languages such as Smalltalk, LISP, Ruby, and Python have used it for years. In a nutshell, a dynamic runtime allows a dynamic language the ability to discover types completely at runtime with no compile-time checks. If you have a background in strongly typed languages (including C#, without dynamic types), the very notion of such a runtime might seem undesirable. After all, you typically want to receive compiletime errors, not runtime errors, wherever possible. Nevertheless, dynamic languages/runtimes do provide some interesting features, including the following: • An extremely flexible code base. You can refactor code without making numerous changes to data types. • A very simple way to interoperate with diverse object types built in different platforms and programming languages. • A way to add or remove members to a type, in memory, at runtime. One role of the DLR is to enable various dynamic languages to run with the .NET runtime and give them a way to interoperate with other .NET code. Two popular dynamic languages that make use of the DLR are IronPython and IronRuby. These languages live in a dynamic universe, where type is discovered solely at runtime. And yet, these languages have access to the richness of the .NET base class libraries. Even better, their codebases can interoperate with C# (or vice versa), thanks to the inclusion of the dynamic keyword.  Note This chapter will not address how the DLR can be used to integrate with dynamic languages. However, details can be found at the IronPython (http://ironpython.codeplex.com) and IronRuby (http://rubyforge.org/projects/ironruby) web sites. The Role of Expression Trees The DLR makes use of expression trees to capture the meaning of a dynamic call in neutral terms. For example, when the DLR encounters some C# code, such as the following: dynamic d = GetSomeData(); d.SuperMethod(12); it will automatically build an expression tree that says, in effect, “Call the method named SuperMethod on object d, passing in the number 12 as an argument.” This information (formally termed the payload) is then passed to the correct runtime binder, which again could be the C# dynamic binder, the IronPython dynamic binder, or even (as explained shortly) legacy COM objects. From here, the request is mapped into the required call structure for the target object. The nice thing about these expression trees (beyond the fact that you don’t need to manually create them) is that this allows us to write a fixed C# code statement, and not worry about what the underlying target 606