Author avatar

Dániel Szabó

Dynamic Types in C#

Dániel Szabó

  • Jan 21, 2020
  • 4 Min read
  • Jan 21, 2020
  • 4 Min read


In the fall of 2009 Microsoft released version 4.0 of C#, which included multiple new features such as Named and Optional Parameters, Dynamic Types, Variance, and COM Interoperability. All these features gave new ways to developers to overcome problems in a more elegant a sophisticated way. This guide will introduce you to Dynamic Types and teach you how to wield this powerful feature.

Dynamic typing may be very familiar to you if are already experienced in Python Programming Language. This type is a static type, but an object of type dynamic allows you to bypass static type checking, which happens and compile time, and to assign a type to a variable during runtime. As with everything else, it has it's ups and downs too. Dynamic types are very similar to Reflection, which is also evaluated at runtime, but has more performance impact.

Multiple Dispatch

When you are developing with Object Oriented Programming (OOP), a specific implementation of a virtual or abstract method is called at runtime based on your runtime type of the object or objects passed as this to one of the member functions. Double dispatch is a specific case of this when you have two methods with the same name that behave differently based on the type of arguments.

Let's look at an example.

1using System;
3namespace Pluralsight
6    public abstract class Base { }
7    public class A1 : Base { }
8    public class A2 : Base { }
10    public class Test
11    {
12        public static void Main(string[] args)
13        {
14            Base a1 = new A1();
15            Base a2 = new A2();
17            Dispatcher(a1, a2); 
18            Dispatcher(a2, a1); 
19            System.Console.ReadKey();
20        }
22        public static void Dispatcher(Base a1, Base a2) 
23        {
24            dynamic x = a1;
25            dynamic y = a2;
27            Method(x, y);
29        }
30        public static void Method(A1 a1, A2 a2) //1
31        {
32            Console.WriteLine("(A1,A2)");
33        }
34        public static void Method(A2 a2, A1 a1) //1
35        {
36            Console.WriteLine("(A2,A1)");
37        }
38    }

Here we have two classes defined as A1 and A2 that inherit from the Base abstract class. In our main function we instantiate these classes, then call our method, Dispatcher, with our instances in a different order. This method is special because it creates our x and y variables, which allow us to demonstrate the power of dynamic types. Then, in the same method, we call Method, which will behave differently based on the arguments. The first Dispatcher(a1, a2); call will return (A1,A2)as the order of the passed arguments and matches the //1 definition of Method. The second call, Dispatcher(a2, a1);, will return (A2,A1), as that is the order matching the //2 definition of Method. This could have many use cases, and it is very similar to implementing the switch construct.

Square Root

This example is about a small function we want to use to calculate the square root of a specific number. The Math.sqrt() function expects a variable of type float, and this is where dynamic types come to the rescue.

Let's look at another example.

1using System;
3namespace Pluralsight
6    public class Test
7    {
8        public static void Main(string[] args)
9        {
10            decimal foo = 10;            
11            double sroot = Math.Sqrt(foo);
12            System.Console.WriteLine($"The square root of {foo} is {sroot}!");
13            System.Console.ReadKey();
14        }
15    }

This is going to fail to compile as the compile-time type checking identifies that the type decimal cannot be converted to double. However, if we swap out the decimal foo = 10; to dynamic foo = 10; the compile time error goes away and the following result is produced.

1The square root of 10 is 3.16227766016838!


Dynamic typing allows faster development while sacrificing some speed, while static typing allows for faster and more reliable code with easy-to-hunt down bugs and problems. All in all, this is a very cool feature that altogether improves the C# experience and is widely used by developers since the pros outweigh the cons. I hope this has been informative to you and I would like to thank you for reading it.