By the year 2010, Microsoft included in .NET a new static type called “dynamic“. This type, from my experience seeing other’s guys code, is rarely used, but I’ve found that in some scenarios can make our code much more readable and logic.

In this article, I’ll try to explain what makes dynamic so different from the rest of the .NET types, and I’ll give you a clear example of it’s power in a demo project using “dynamic overload“.

As always, you can clone the demo project from my Bitbucket repository, or download it via .ZIP file:

dynamic

The main difference between dynamic and the rest of .NET types, is that dynamic bypasses static type check at compile time, behaving like an object type, and leaving all the validation at runtime. You can see the difference in this example:

Given this public class:

public class MyClass {
     public string Prop { get; set; }
}

With the class itself:

MyClass mc = new MyClass();
// We are good here
mc.Prop = "hello";
// This won't compile ... 'AnotherProp' doesn't exist!
mc.AnotherProp = "world";

With object:

object obj = new MyClass();
// This doesn't compile either, as "object" class doesn't have such property
obj.Prop = "hello";

With dynamic:

dynamic dynobj = new MyClass();
mc.Prop = "hello";
// This will compile!! Of course, it'll throw an exception
// at runtime since the property is not there
md.AnotherProp = "world";

Ok, you must be thinking, 41 lines of article to show you how something doesn’t compile, or in the best case scenario, explodes at runtime? Great article… but wait! as always, the best is yet to come…

Dynamic overload

As I told you before, in this article we’re gonna focus in one of the usages of dynamic that I find very interesting. Dynamic overload!

This technique will render your code clear, maintainable and elegant, anyway, reflection and type check can be some faster. So, if you’re very very worried about performance, and it’s critical in your app, maybe this isn’t the option.

Background

Let’s create a background context to solve. First, we will use the “traditional” solution and then, a dynamic overloaded solution.

We have a collection of objects inheriting from the same class, but when we iterate through them, we need to do different things depending on the type itself. For example, In a list of customers, we could have physical people and companies like this:

public abstract class Customer
{
    public string CustomerCode { get; set; }
    public decimal CreditLine { get; set; }
}

public class PhysicalCustomer : Customer
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

public class CompanyCustomer : Customer
{
    public string CompanyName {get; set; }
    public string ContactName { get; set; }
    public string ContactSurname { get; set; }
    public string Position { get; set; }
}

Now I want to send a mail to my customer base, with a personal greeting depending on which type of customer I’m talking to.

The “traditional” way

If we use the “traditional” way, we should check the type of every object in the iteration like this:

private static void Greet(Customer obj)
{
    if (obj is PhysicalCustomer)
    {
        var cust = (PhysicalCustomer) obj;
        Console.WriteLine("Hello {0} {1}. You have {2:c} available in your personal credit line.", 
            cust.Name, cust.Surname,cust.CreditLine);
    }
    else if (obj is CompanyCustomer)
    {
        var cust = (CompanyCustomer) obj;
        Console.WriteLine("Hello {0} {1}, {2} at {3}. You have {4:c} available in your company's credit line.",
            cust.ContactName,cust.ContactSurname,cust.Position, cust.CompanyName,cust.CreditLine);
    }
}

Hey! Why not? It’s a good way, but it has caveats. The first and foremost is that you can have lots of different object types inheriting from Customer (aka kinds of customer). In that case you’ll end with a very, very, large list of if (...) else if (....) else if (....), and that would make your code quite unreadable and a hell to maintain!

This is where dynamic kicks in very strong…

The dynamized version

The dynamic overload solution for this scenario is giving Greet() a dynamic parameter type. This way the method itself won’t know what parameter type is passed until runtime. That allows us to make a call to another overloaded bunch of methods which will automagically be “filtered” by .NET at runtime to match the best parameter’s type overload.

Huh? sounds complicated? Not at all.. here goes the implementation:

private static void DynGreet(PhysicalCustomer cust)
{
    Console.WriteLine("Hello {0} {1}. You have {2:c} available in your personal credit line.",
        cust.Name, cust.Surname, cust.CreditLine);
}

private static void DynGreet(CompanyCustomer cust)
{
    Console.WriteLine("Hello {0} {1}, {2} at {3}. You have {4:c} available in your company's credit line.",
        cust.ContactName, cust.ContactSurname, cust.Position, cust.CompanyName, cust.CreditLine);
}

// This overload is optional, but it's a good practice to catch any
// unwanted call to the method. Any type without it's own overload
// will fallback here as all objects inherit from "object"
private static void DynGreet(object cust)
{
    throw new ArgumentException(string.Format("Wrong object type ({0})",cust.GetType()));
}

private static void Greet(dynamic obj)
{
    // OOoopps... did you send me a null? No way!
    if (obj == null) throw new NullReferenceException("obj");
    // Choose the best overload
    DynGreet(obj);
}

You may think: “But, I could make that dynamic be object and it’ll work the same…” Wrong! If the method implements an object parameter, in the method scope, it’ll keep being object, not PhysicalCustomer or CompanyCustomer, so when we call DynGreet() it would always call the last (object) overload… that’s the difference about using dynamic instead of object.

DynGreeter full code

Here is the complete demo code in case you want to run it on your computer:

using System;
using System.Collections.Generic;

namespace DynGreeter
{

    public abstract class Customer
    {
        public string CustomerCode { get; set; }
        public decimal CreditLine { get; set; }
    }

    public class PhysicalCustomer : Customer
    {
        public string Name { get; set; }
        public string Surname { get; set; }
    }

    public class CompanyCustomer : Customer
    {
        public string CompanyName {get; set; }
        public string ContactName { get; set; }
        public string ContactSurname { get; set; }
        public string Position { get; set; }
    }


    class Program
    {
        private static void DynGreet(PhysicalCustomer cust)
        {
            Console.WriteLine("Hello {0} {1}. You have {2:c} available in your personal credit line.",
                cust.Name, cust.Surname, cust.CreditLine);
        }

        private static void DynGreet(CompanyCustomer cust)
        {
            Console.WriteLine("Hello {0} {1}, {2} at {3}. You have {4:c} available in your company's credit line.",
                cust.ContactName, cust.ContactSurname, cust.Position, cust.CompanyName, cust.CreditLine);
        }

        // This overload is optional, but it's a good practice to catch any
        // unwanted call to the method. Any type without it's own overload
        // will fallback here as all objects inherit from "object"
        private static void DynGreet(object cust)
        {
            throw new ArgumentException(string.Format("Wrong object type ({0})",cust.GetType()));
        }

        private static void Greet(dynamic obj)
        {
            // OOoopps... did you send me a null? No way!
            if (obj == null) throw new NullReferenceException("obj");
            // Choose the best overload
            DynGreet(obj);
        }

        private static List<Customer> GetCustomers()
        {
            return new List<Customer>
            {
                new PhysicalCustomer()
                {
                    CustomerCode = "doejohn01",
                    Name = "John",
                    Surname = "Doe",
                    CreditLine = 2000
                },
                new CompanyCustomer()
                {
                    CustomerCode = "gmotors01",
                    CompanyName = "General Motors",
                    ContactName = "Rich",
                    ContactSurname = "Man",
                    Position = "CTO",
                    CreditLine = 50000
                }
            };
        }

        private static void PressAnyKey()
        {
            Console.WriteLine();
            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }

        static void Main(string[] args)
        {
            // Let's do the greetings!
            GetCustomers().ForEach(Greet);
            PressAnyKey();
        }
    }
}

Wrapping up, the DynExceptionHandler

Here’s another example in a very common scenario: Exception handling. We want to act different given different kinds of exception that should raise in our application. The “traditional” and easy way would be this:

try
{
    WhateverYouWantToDo();
}
catch (NullReferenceException ex)
{
    // NullReferenceException handling code goes here
}
catch (DivideByZeroException ex)
{
    // DivideByZeroException handling code goes here
}
catch (NotImplementedException ex)
{
    // NotImplementedException handling code goes here
}
catch (Exception ex)
{
    // Fallback exception handling goes here...
}

Instead of this list of catch clauses (that could go on forever), you can create a static class to handle all the exceptions and log/handle whatever you need depending on the exception type like this:

public class DynExceptionHandler
{
    private static void DynHandle(NullReferenceException ex)
    {
        Console.WriteLine("Null reference exception thrown!");
        Trace.TraceError("{0}",ex);
    }

    private static void DynHandle(DivideByZeroException ex)
    {
        Console.WriteLine("Divide by zero exception thrown!");
        Trace.TraceError("{0}", ex);
    }

    private static void DynHandle(NotImplementedException ex)
    {
        Console.WriteLine("Not implemented exception thrown!");
        Trace.TraceError("{0}", ex);
    }

    private static void DynHandle(Exception ex)
    {
        Console.WriteLine("Unknown exception type! {0}", ex.GetType());
        Trace.TraceError("{0}",ex);
    }

    private static void DynHandle(object ex)
    {
        Console.WriteLine("Not an exception!!! {0}", ex.GetType());
        Trace.TraceError("{0}", ex);
    }

    public static void HandleException(dynamic ex)
    {
        if (ex == null) 
            DynHandle(new Exception("Null Exception thrown?",ex));
        DynHandle(ex);
        Console.WriteLine();
        Console.WriteLine();
    }
}

In this class, you have all your Exception types well dressed and placed, and, the most important is that you can add any overload anytime you want without changing a line of decision code. Meaning that the new overload will be hit when the parameter type matches.

Using this class, your code would look much, much, more simpler…

try
{
    WhateverYouWantToDo();
}
catch (Exception ex)
{
    DynExceptionHandler.HandleException(ex);
}

Nice, huh? This is elegant code…

Download

And we are done explaining!

In case you didn’t see it at the beginning (or you’re too lazy to scroll up), I put here the links to the GIT repository with the DynExceptionHandler demo project, and another for the ZIP file in case you don’t use GIT.

Thank you!

Today it’s been a long article, so I hope my efforts haven’t been in vain and you have enjoyed the read. This is a nice trick to keep you code simple, readable and elegant… As always, keep tuned for new articles!

Peace!

Follow me

Joan Vilariño

Senior .NET Developer at Ohpen
Developer for more than 25 years and IT, gadget, mobile and electronics enthusiast working and publishing from Barcelona.
Follow me