Dynamic in C#

A quick glance at the dynamic keyword

It’s just a quick-and-dirty code demo, to show the basic usage of dynamic keyword and difference with other similar constructs. This does not cover any theories at all. If you’re looking for more in-depth knowledge, go to MSDN or other good resources that can give better explanations.

We’ll also look at var and object to see the contrast.

Few very basic things to note:

  1. The dynamic keyword adds some dynamic capabilities to the language, which means - in brief, you can use dynamically typed objects in your code (in contrary to all the strongly typed objects you have seen in C#).

  2. But C# still is a statically typed language in most senses. Use dynamic only if static typing is not serving your use-case.

  3. From Scott Henselman’s blog - Dynamically typed objects are still statically typed, as dynamic. Yes, the type of those objects are dynamic, and internally object to the CLR. But do not break your head with that, read on.

  4. Declaring something as dynamic does this one important thing - defers all the type-checks and invocation till the run-time. Basically, all the statements with dynamic stuffs are ignored at compile-time (syntax is checked though) and executed only at runtime.

  5. Use of dynamic gives this one benefit - you can use the same variable to store different types of data (can also be done with object) and can seamlessly invoke members on them (NOT possible with object), without having to type cast or using reflection!

  6. As we all have heard so many times With great power comes great responsibility, using of dynamic gives you the responsibility of writing the correct-and-safe code, as compiler will not do that for you. If you screw up something, your application will break at run-time.

  7. This was introduced mostly to work with systems and codes that does not follow .NET style strong typing and using dynamic will reduce lot of boilerplate code. It is particularly useful when working with COM and languages like Python, Ruby etc. So, again use dynamic only if you really need to.

  8. Big downside of using dynamic - losing compile-time checks, increased probability of errors.

Now the code demo:

class Demo //demo class used in code
{
    public string Name { get; }
    internal string GetId()
    {
        return "Cool_ID";
    }
}
A quick glance at var

This var is nothing but a shorthand for defining types, also called implicit typing. They are still statically and strongly typed at compile time, only thing is the type is inferred by compiler at declaration.

//not allowed, it must be initialized
var x;
//z is inferred to be int
var z = 3;
//will not compile, as z IS int, not string
z = "woohoo";
//doesn't compile as the type cannot be inferred
var y = null;

Now we’ll see dynamic in action.

dynamic x = 3;
//allowed, as different data types can be stored in dynamic
x = "woohoo";
x = 0.5; //same as above
x += "hello"; //works fine and produces "0.5hello"
x = new Demo(); //works, obviously
//compiles fine, as no check is done at compile time.
//Runs fine as well, as the code is right
x = x.GetId();
//still compiles, BUT throws RuntimeBinderException: 
//''string' does not contain a definition for 'GetWhatIsNotThere''
x = x.GetWhatIsNotThere();

In the last line, the code still compiles - because compiler skips all the checks for variable declared to be dynamic!

The same code with object

//to show difference with object
object y = 3;
//compiles and runs, as all types are still objects
y = "jassala";
y = 0.5; //same
y += "hello"; //same, produces "0.5hello"
y = new Demo(); //works, for same reason
//DIFFERENCE: This gives compile error
//object does not have a definition of GetId
y = y.GetId(); 
//DOESN'T compile for same reason
y = y.GetWhatIsNotThere();

dynamic in method return

This is for illustration only. Understand how unsafe and unpredictable the code can be. Do NOT try this at home or work unless you unerstand exactly what you are doing.

public dynamic DynamicMethod(string s)
{
    dynamic result;
    try
    {
        int num;
        int.TryParse(s, out num);
        result = num;
    }
    catch (Exception ex)
    {
        result = ex;
    }
    return result;
}
comments powered by Disqus