C# Dynamic

C# Dynamic

Dynamics is one of the features of C# that sometimes confuses some developers but it’s actually pretty easy.Let me give you some background information.Programming languages are divided into two types —

  • Statically-typed languages
  • Dynamically-typed languages.

Or in short, we can say static languages or dynamic languages.Examples of static languages are C# and Java. Dynamic languages are like Ruby, Javascript, Python, and so on.

But what’s the difference?

Type resolution-

  • Static languages: at compile-time.
  • Dynamic languages : at run-time

In static languages resolution of types: members, properties, methods is done at compile-time.So if we try to access a method that is not defined in an object and when we compile the application getting an immediate feedback that’s telling us that method or property is not found on that object.

With dynamic languages the resolution of types: properties, members, methods is done at run-time.

But what’s the benefit of that?

  • Static languages: early feedback (compile-time).
  • Dynamic languages: easier and faster to code.

First, I’m not an expert in programming languages, but based on my understanding, dynamic languages are a little bit easier and faster to write code with. But on the flip side, because we lose compile-time checking we have to write more unit tests to make sure the application behaves properly at run-time.

History of dynamic in C#

C# started as a static language but in .NET Framework version four they added dynamic capability to it and the intention was to improve interoperability with COM(e.g. office applications) or dynamic languages in .NET like IronPython. If you’re writing code for Microsoft Office applications such as Word or Excel dynamic is a feature that is going to help you a lot.Without dynamics, you have to use Reflection.

What is Reflection?

Reflection is a way to inspect the metadata about the type and access properties and methods. Let me show you an example.

using System;

namespace Dynamic
{
    class Program
    {
        static void Main(string[] args)
        {
            object obj = "john";
            obj.GetHashCode();
        }
    }
}

Suppose, I have an object here. Give it a name of “obj” and assign it to a string “john”. I can call the GetHashCode method here like this  obj.GetHashCode(); and that’s pretty easy. But with Reflection, if I want to call that method my code will end up looking like this.

using System;

namespace Dynamic
{
    class Program
    {
        static void Main(string[] args)
        {
            object obj = "john";
            //obj.GetHashCode();
            var methodInfo = obj.GetType().GetMethod("GetHashCode");
            methodInfo.Invoke(null, null);
        }
    }
}

First, I get the type of that object and then I get a reference to a method called GetHashCode  obj.GetType().GetMethod("GetHashCode");  and that returns a methodInfo object. Now, I can invoke methodInfo like this  methodInfo.Invoke(null, null); and pass some weird arguments here.As you see it, this code is not very beautiful. So Reflection is a little bit difficult and messy.The benefit of dynamic is that.

Let’s say, you’re getting an excelObject and you know that object should have some method called that I don’t know. let’s define an object here  object excelObject = "terry";  I set it to a string for now just for simplicity because I really don’t have excelObject here. let’s say, you know, I’d run-time that object should have a method called Optimize.

You see that we get compile-time error because the object class here does not have a method called Optimize. With dynamic, we can easily resolve this problem without having to use Reflection.

With dynamic, it looks like much cleaner. So that’s how you use Dynamics in C#.

But how does all the magic happen as in resolving types, properties, members at run-time?

You should be familiar with CLR or Common Language RuntimeIt is .NET’s virtual machine that gets

your compiled code which is in intermediate language(IL). Then, converts that or recompose that into machine code at runtime. In.NET Framework version four, they added a new component called DLR which is a Dynamic Language Runtime. So DLR sits on top of CLR and gives dynamic language capabilities to C#.

Now, let’s take a look at a few other things about Dynamics –

using System;

namespace Dynamic
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic name = "john";
            name = 10;
        }
    }
}

I have defined a dynamic type name here and assign it to “john”. Then, the next line, I can assign an integer to it And that’s perfectly fine. With static types, like object, int, string or whatever, this is not possible — we’re going to get an exception. But if I run this code the application runs successfully.There are no exceptions. Let’s inspect this, I put a breakpoint here with.Run the application in debug mode.Continue execution with F10. Let’s put a watch on the name variable.Take a look here.

So name is a dynamic and it’s runtime type is a string. But if I continue execution with F10-

Now its runtime type changes to integer and that’s one of the key differences between dynamic types and static types. With dynamic types, we can do whatever we want with them. I think that’s what makes them powerful in terms of writing code faster and easier.

Now, let me show you another example here-

using System;

namespace Dynamic
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic name = "John";
            name++;
        }
    }
}

Here, I tried to apply a ‘++’ operator to this name variable. Let run the application to see what happens?

This time we got an exception. Unhandled exception, its subtype RuntimeBinderException which is a popular exception when working with dynamic types and the exception message says- “operator ‘++’ cannot be applied to operand of type ‘string’ “. So at runtime, the type of name variable would be string and of course, we cannot do that increment with a string. That’s the reason I told you — “with dynamic types, we need to write more unit tests to make sure application behaves properly at runtime”.

dynamic Vs var

Let’s take a look at another example –

I’m defining a dynamic called “a” set it to 10 and “b” set to 5. This time, I’m going to define a variable with var. Now, var is not dynamic. var is basically a shorthand way of writing code and letting the computer decide what type a given variable should be. So if I say, var c equals empty string and I hover my mouse over var then found var is a string –

It’s a short way of writing code. I could just write string here but var is a little bit shorter.

Now, the interesting thing here is if I define “c” as “a plus b”- 

because a and b are dynamicc will end up being dynamic. Let’s put a breakpoint here .Run the application in debug mode.I’m going to do this watch here and put a, b, c on watch.So, continue execution with F10.

So a is dynamic and this runtime type is integer — so is  and so is c. So when you use dynamic variables in an expression the expression will end up being dynamic as well.

One more thing you need to know about dynamics is conversions or castsMost often, with dynamics you get implicit conversion from and to the target type. So let me show you an example here.

So I define an integer called “i” and set it to five. Now I can define a dynamic called “d” and set it to “i”. In this case, I didn’t have to specify a type cast or conversion. At runtime, d will end up being an integer. Let’s verify that. So continue execution with F10. I put d here, in the watch window. So “d” is a dynamic and it’s runtime type is integer. Similarly, we can put dynamic on the right side of the assignment operator without the need to do any explicit casting-

So if I define a long “l” here, I can put d inside long. At runtime, d will be an integer, and of course, we can’t put an integer in a long variable without explicit casting. So the lesson is — when converting from dynamic to static types, if the runtime type of the dynamic object is implicitly convertible to the target type, you don’t need to cast it. So let’s verify this.

Here,  “l” as you see it’s long and its value is five and “d” is of course dynamic and its runtime type is integer. Well, I think it is enough about Dynamic type. I hope you enjoyed it and thank you for reading.

Leave a Reply

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