Dynamic C# & DLR (Part I): Overview

Intro

As part of metaprogramming existing techniques, we are going to review all the dynamic capabilities of C# language and try to provide a clear picture about DLR (Dynamic Language Runtime) in general. According to Microsoft, DLR is a Runtime Environment that includes a set of services that provides a rich ecosystem for dynamic languages to the CLR. The DLR makes it easier to develop dynamic languages to run on the .NET Framework and to add dynamic features to statically typed languages. From high perspective, a dynamic language is a language that allows modifying code at Runtime.

Dynamic C# can be used for enhancing code productivity and readability, and its use can also simplify the code being perfect complement to standard static C# Code. Dynamic C# provides with a common set of dynamic features to C# and DLR increase the .NET interoperability by including dynamic objects to C# (and VB.NET) which allows .NET integration with other dynamic languages like Python. In the same way, DLR allows us to create custom dynamic types for supporting dynamic operations.

Behind the scenes, DLR make use of extended version of Expression Trees for including nodes and control flow as main vehicle for representing language semantics. DLR also includes a specific set of interfaces and types which represent the basis for elaborated dynamic scenarios. Call Site Caching is another key feature of DLR which increase performance significantly

DLR was introduced by Microsoft at .NET Framework 4.0 Release, and not only added support for dynamic language feature to C# also added a set of new other languages to run on top CLR like IronRuby, IronPhyton and ClojureCLR

Main DLR benefits are the following ones:

  1. Enables including dynamic behaviour into statically typed languages: One of the main vehicle for this is by using “dynamic” keyword in our C# code.

 

  1. Simplifies creation or porting of dynamic languages to the .NET: By the use of ExpressionTrees language implementers can focus on unique language features and avoid to creating custom semantic analizers, parsers or code generators. This time .NET framework will do a lot code analysis and code generation.

 

  1. Enables assembly sharing between languages: In addition to interoperation between statically typed language and dynamic ones, DLR provides support for sharing libraries between languages. Objects implemented in one language can be used by other languages (we can create a class in C# and pass it to IronRuby code). This is possible by using types like DynamicObject or ExpandoObject and interfaces like IDynamicMetaObjectProvider

 

  1. Call site caching: It´s the internal mechanic by which resolving types are only required once.

Basically dynamic type allows avoiding compile time checking delegating it to runtime by using dynamic binding,

 

Why to use Dynamic C#

First of all, it worth to mention one of main purposes of dynamic C# is to complement static statically type C# code. That´s is to say, dynamic C# can help us to write more efficient, simpler and readable code under special scenarios such as:

  • When we don´t know object type at compile time
  • When we know the type at compile type but we can´t tell the compiler what is
  • When dealing with weakly typed data like JSON or XML
  • When interoperating with COM components (allowing create instances of COM types whiteout needing to reference the interop assembly)
  • When we need to interoperate with other dynamic languages like python

In addition to that, dynamic code has proven a more efficient approach (simplifying code and improving readability) in

  • Replacing Reflection Code
  • Working with COM components
  • Dynamic JSON Processing
  • XAML Binding by using dynamic types
  • Writing data access code
  • Creating Automated Tests

At this point we need to note dynamic commonly involves minor disadvantage in terms of performance, so programmers need to achieve a proper balance between static typing for safety and performance, and dynamic one when some flexibility is needed . In later topics we will see examples for each of them

Binding in Dynamic C#

Binding is a key concept to understand when dealing with dynamic C#. Before of all, it´s possible to define binding as the linking of syntactic element, such as the name of a method, with a logical program component. Every time we compile our statically typed code a static binding is performed in order to preserve code integrity for instance, let´s suppose we have the following method

public void MyMethod(Person person)
{
  try
  {
    PersonHelper helper = new PersonHelper();
    helper.DeletePerson(person.Id);
  }
  catch(Exception ex)
  {
  //implement exception handling here
  }
}

When we run the compiler, a static binding checking is performed for notifying that all is ok. We update the code in the following way

public void MyMethod(Person person)
{
     try
     {
          PersonHelper helper = new PersonHelper();
          helper.NotExistingMethod(person.Id);
          helper.DeletePerson(person.Id);
     }
     catch (Exception ex)
     {
          //implement exception handling here!!
     }
 }

The compiler will knows that NotExistingMethod() is not present at PersonHelper class, this generates a compilation error and program can no to be executed.

Dynamic C# is used dynamic binding which operates in a different way. When we declare our helper as dynamic the binding will occur at runtime preventing us from compilation errors. The compiler does not know if the method exists:

public void MyMethod(Person person)
{
   try
   {
     //this compiles Ok!
     dynamic helper = new PersonHelper();
     helper.NotExistingMethod(person.Id);
     helper.DeletePerson(person.Id);
   }
   catch (Exception ex)
   {
      //implement exception handling here!!
   }
}

At this point, it´s important to note type safety is still enforced but at runtime instead of compile time. If finally the method doesn´t exists a RuntimeBinderException will be raised.

It worth to mention that DLR work closely together with language binders to make the code execute at runtime

Relation between Object and Dynamic types

Some confusing point when dealing with dynamic is that there is no specific underlying type in C# that represents the dynamic keyword. If we disassembly our code and inspect the IL we´ll see that our dynamic variables are in fact System. Object types. It will be the compiler the responsible for providing these objects with proper dynamic behaviour. In C# the structure of System.Object reference and dynamic one are basically the same; the only difference is that a dynamic allows invoking dynamic operations over the object that points to. In fact, if we try to define to overloads of a given method one with object param and another one with dynamic type the compiler will raise an error because identify those params as the same type:

static void ShowMessage(object dy)
{
   Console.WriteLine(string.Format("dy has a [{0}] type and it´s equals to {1}", dy.GetType(), dy));
}
 
static void ShowMessage(dynamic dy)
{
  Console.WriteLine(string.Format("dy has a [{0}] type and it´s equals to {1}", dy.GetType(), dy));
}

In fact, if we create a dynamic member for given class we will see how the compiler will add System.Runtime.CompilerServices.DynamicAttribute over this member

public class Country
{
   public Guid Id { get; set; }
   public string Name { get; set; }
   public dynamic Description { get; set; }
}

And the corresponding views at ILSpy:

Dynamic C# 1
Dynamic C# 1
Dynamic C# 2
Dynamic C# 2

Conversions in Dynamic C#

Dynamic type can be implicitly converted to and from other types. No explicit casting is required, as can be seen from following dummy code:

static void Main(string[] args)
{
   string str = "Hi there!";
   dynamic dy = str;
   string str2 = dy;
 
   Console.WriteLine(string.Format("str=[{0}], dy=[{1}], str2=[{2}]",str,dy,str2));
 
   Console.WriteLine("\n\nPress enter to exit");
   Console.ReadLine();
}

When we execute the conversion is performed at runtime

Dynamic C# 3
Dynamic C# 3

But if we try to run this:

static void Main(string[] args)
{
   string str = "Hi there!";
   dynamic dy = str;
   double db = dy;
 
  Console.WriteLine(string.Format("str=[{0}], dy=[{1}], str2=[{2}]", str, dy, db));
 
  Console.WriteLine("\n\nPress enter to exit");
  Console.ReadLine();
}

A RuntimeBinderException will be raised:

Dynamic C# Overview 4
Dynamic C# Overview 4

Nevertheless we can also “redefine” or update the value-type that specific dynamic type is holding, following code is perfectly valid

static void Main(string[] args)
{
   dynamic dy = "Hi there!";
   Console.WriteLine(string.Format("dy has a [{0}] type and it´s equals to {1}", dy.GetType(), dy));
 
   dy = 12345;
   Console.WriteLine(string.Format("dy has a [{0}] type and it´s equals to {1}", dy.GetType(), dy));
 
  Console.WriteLine("\n\nPress enter to exit");
  Console.ReadLine();
}

When we run the console:

Dynamic C# Overview 5
Dynamic C# Overview 5

At this point, it worth mentioning some differences about the use of “var” and “dynamic” when defining variables. Let´s suppose the following sample:

static void Main(string[] args)
{
   dynamic dy = 12345; 
   int i = 12345;
   var i2 = 12345;
}

Main differences between these variables have to do with the type of variable at Compile time or Runtime: dy type is dynamic at compile time but integer at runtime, i is integer at compile and runtime and i2 is also and integer at compile and runtime (the type is inferred).

In next article we will see different dynamic samples in action for showing how dynamic flexibility can improve the quality of our code

That´s all see you on the road!

0 comments on “Dynamic C# & DLR (Part I): OverviewAdd yours →

Leave a Reply

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