[c#] What is the 'dynamic' type in C# 4.0 used for?

C# 4.0 introduced a new type called 'dynamic'. It all sounds good, but what would a programmer use it for?

Is there a situation where it can save the day?

This question is related to c# .net dynamic c#-4.0

The answer is


The best use case of 'dynamic' type variables for me was when, recently, I was writing a data access layer in ADO.NET (using SQLDataReader) and the code was invoking the already written legacy stored procedures. There are hundreds of those legacy stored procedures containing bulk of the business logic. My data access layer needed to return some sort of structured data to the business logic layer, C# based, to do some manipulations (although there are almost none). Every stored procedures returns different set of data (table columns). So instead of creating dozens of classes or structs to hold the returned data and pass it to the BLL, I wrote the below code which looks quite elegant and neat.

public static dynamic GetSomeData(ParameterDTO dto)
        {
            dynamic result = null;
            string SPName = "a_legacy_stored_procedure";
            using (SqlConnection connection = new SqlConnection(DataConnection.ConnectionString))
            {
                SqlCommand command = new SqlCommand(SPName, connection);
                command.CommandType = System.Data.CommandType.StoredProcedure;                
                command.Parameters.Add(new SqlParameter("@empid", dto.EmpID));
                command.Parameters.Add(new SqlParameter("@deptid", dto.DeptID));
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        dynamic row = new ExpandoObject();
                        row.EmpName = reader["EmpFullName"].ToString();
                        row.DeptName = reader["DeptName"].ToString();
                        row.AnotherColumn = reader["AnotherColumn"].ToString();                        
                        result = row;
                    }
                }
            }
            return result;
        }

I am surprised that nobody mentioned multiple dispatch. The usual way to work around this is via Visitor pattern and that is not always possible so you end up with stacked is checks.

So here is a real life example of an application of my own. Instead of doing:

public static MapDtoBase CreateDto(ChartItem item)
{
    if (item is ElevationPoint) return CreateDtoImpl((ElevationPoint)item);
    if (item is MapPoint) return CreateDtoImpl((MapPoint)item);
    if (item is MapPolyline) return CreateDtoImpl((MapPolyline)item);
    //other subtypes follow
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

You do:

public static MapDtoBase CreateDto(ChartItem item)
{
    return CreateDtoImpl(item as dynamic);
}

private static MapDtoBase CreateDtoImpl(ChartItem item)
{
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

private static MapDtoBase CreateDtoImpl(MapPoint item)
{
    return new MapPointDto(item);
}

private static MapDtoBase CreateDtoImpl(ElevationPoint item)
{
    return new ElevationDto(item);
}

Note that in first case ElevationPoint is subclass of MapPoint and if it's not placed before MapPointit will never be reached. This is not the case with dynamic, as the closest matching method will be called.

As you might guess from the code, that feature came handy while I was performing translation from ChartItem objects to their serializable versions. I didn't want to pollute my code with visitors and I didn't want also to pollute my ChartItem objects with useless serialization specific attributes.


COM interop. Especially IUnknown. It was designed specially for it.


An example of use :

You consume many classes that have a commun property 'CreationDate' :

public class Contact
{
    // some properties

    public DateTime CreationDate { get; set; }        
}

public class Company
{
    // some properties

    public DateTime CreationDate { get; set; }

}

public class Opportunity
{
    // some properties

    public DateTime CreationDate { get; set; }

}

If you write a commun method that retrieves the value of the 'CreationDate' Property, you'd have to use reflection:

    static DateTime RetrieveValueOfCreationDate(Object item)
    {
        return (DateTime)item.GetType().GetProperty("CreationDate").GetValue(item);
    }

With the 'dynamic' concept, your code is much more elegant :

    static DateTime RetrieveValueOfCreationDate(dynamic item)
    {
        return item.CreationDate;
    }

Another use case for dynamic typing is for virtual methods that experience a problem with covariance or contravariance. One such example is the infamous Clone method that returns an object of the same type as the object it is called on. This problem is not completely solved with a dynamic return because it bypasses static type checking, but at least you don't need to use ugly casts all the time as per when using plain object. Otherwise to say, the casts become implicit.

public class A
{
    // attributes and constructor here
    public virtual dynamic Clone()
    {
        var clone = new A();
        // Do more cloning stuff here
        return clone;
    }
}

public class B : A
{
    // more attributes and constructor here
    public override dynamic Clone()
    {
        var clone = new B();    
        // Do more cloning stuff here
        return clone;
    }
}    

public class Program
{
    public static void Main()
    {
        A a = new A().Clone();  // No cast needed here
        B b = new B().Clone();  // and here
        // do more stuff with a and b
    }
}

The dynamic keyword was added, together with many other new features of C# 4.0, to make it simpler to talk to code that lives in or comes from other runtimes, that has different APIs.

Take an example.

If you have a COM object, like the Word.Application object, and want to open a document, the method to do that comes with no less than 15 parameters, most of which are optional.

To call this method, you would need something like this (I'm simplifying, this is not actual code):

object missing = System.Reflection.Missing.Value;
object fileName = "C:\\test.docx";
object readOnly = true;
wordApplication.Documents.Open(ref fileName, ref missing, ref readOnly,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing);

Note all those arguments? You need to pass those since C# before version 4.0 did not have a notion of optional arguments. In C# 4.0, COM APIs have been made easier to work with by introducing:

  1. Optional arguments
  2. Making ref optional for COM APIs
  3. Named arguments

The new syntax for the above call would be:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

See how much easier it looks, how much more readable it becomes?

Let's break that apart:

                                    named argument, can skip the rest
                                                   |
                                                   v
wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);
                                 ^                         ^
                                 |                         |
                               notice no ref keyword, can pass
                               actual parameter values instead

The magic is that the C# compiler will now inject the necessary code, and work with new classes in the runtime, to do almost the exact same thing that you did before, but the syntax has been hidden from you, now you can focus on the what, and not so much on the how. Anders Hejlsberg is fond of saying that you have to invoke different "incantations", which is a sort of pun on the magic of the whole thing, where you typically have to wave your hand(s) and say some magic words in the right order to get a certain type of spell going. The old API way of talking to COM objects was a lot of that, you needed to jump through a lot of hoops in order to coax the compiler to compile the code for you.

Things break down in C# before version 4.0 even more if you try to talk to a COM object that you don't have an interface or class for, all you have is an IDispatch reference.

If you don't know what it is, IDispatch is basically reflection for COM objects. With an IDispatch interface you can ask the object "what is the id number for the method known as Save", and build up arrays of a certain type containing the argument values, and finally call an Invoke method on the IDispatch interface to call the method, passing all the information you've managed to scrounge together.

The above Save method could look like this (this is definitely not the right code):

string[] methodNames = new[] { "Open" };
Guid IID = ...
int methodId = wordApplication.GetIDsOfNames(IID, methodNames, methodNames.Length, lcid, dispid);
SafeArray args = new SafeArray(new[] { fileName, missing, missing, .... });
wordApplication.Invoke(methodId, ... args, ...);

All this for just opening a document.

VB had optional arguments and support for most of this out of the box a long time ago, so this C# code:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

is basically just C# catching up to VB in terms of expressiveness, but doing it the right way, by making it extendable, and not just for COM. Of course this is also available for VB.NET or any other language built on top of the .NET runtime.

You can find more information about the IDispatch interface on Wikipedia: IDispatch if you want to read more about it. It's really gory stuff.

However, what if you wanted to talk to a Python object? There's a different API for that than the one used for COM objects, and since Python objects are dynamic in nature as well, you need to resort to reflection magic to find the right methods to call, their parameters, etc. but not the .NET reflection, something written for Python, pretty much like the IDispatch code above, just altogether different.

And for Ruby? A different API still.

JavaScript? Same deal, different API for that as well.

The dynamic keyword consists of two things:

  1. The new keyword in C#, dynamic
  2. A set of runtime classes that knows how to deal with the different types of objects, that implement a specific API that the dynamic keyword requires, and maps the calls to the right way of doing things. The API is even documented, so if you have objects that comes from a runtime not covered, you can add it.

The dynamic keyword is not, however, meant to replace any existing .NET-only code. Sure, you can do it, but it was not added for that reason, and the authors of the C# programming language with Anders Hejlsberg in the front, has been most adamant that they still regard C# as a strongly typed language, and will not sacrifice that principle.

This means that although you can write code like this:

dynamic x = 10;
dynamic y = 3.14;
dynamic z = "test";
dynamic k = true;
dynamic l = x + y * z - k;

and have it compile, it was not meant as a sort of magic-lets-figure-out-what-you-meant-at-runtime type of system.

The whole purpose was to make it easier to talk to other types of objects.

There's plenty of material on the internet about the keyword, proponents, opponents, discussions, rants, praise, etc.

I suggest you start with the following links and then google for more:


  1. You can call into dynamic languages such as CPython using pythonnet:

dynamic np = Py.Import("numpy")

  1. You can cast generics to dynamic when applying numerical operators on them. This provides type safety and avoids limitations of generics. This is in essence *duck typing:

T y = x * (dynamic)x, where typeof(x) is T


It evaluates at runtime, so you can switch the type like you can in JavaScript to whatever you want. This is legit:

dynamic i = 12;
i = "text";

And so you can change the type as you need. Use it as a last resort; it i s beneficial, but I heard a lot goes on under the scenes in terms of generated IL and that can come at a performance price.


It makes it easier for static typed languages (CLR) to interoperate with dynamic ones (python, ruby ...) running on the DLR (dynamic language runtime), see MSDN:

For example, you might use the following code to increment a counter in XML in C#.

Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);

By using the DLR, you could use the following code instead for the same operation.

scriptobj.Count += 1;

MSDN lists these advantages:

  • Simplifies Porting Dynamic Languages to the .NET Framework
  • Enables Dynamic Features in Statically Typed Languages
  • Provides Future Benefits of the DLR and .NET Framework
  • Enables Sharing of Libraries and Objects
  • Provides Fast Dynamic Dispatch and Invocation

See MSDN for more details.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to dynamic

Please help me convert this script to a simple image slider Declare an empty two-dimensional array in Javascript? Compiling dynamic HTML strings from database Changing datagridview cell color dynamically What is the difference between dynamic programming and greedy approach? Dynamic variable names in Bash Dynamically Add C# Properties at Runtime How to generate a HTML page dynamically using PHP? Change UITableView height dynamically How to create own dynamic type or dynamic object in C#?

Examples related to c#-4.0

Xml Parsing in C# EPPlus - Read Excel Table How to add and get Header values in WebApi How to make all controls resize accordingly proportionally when window is maximized? How to use jquery or ajax to update razor partial view in c#/asp.net for a MVC project How to get first record in each group using Linq How to get first object out from List<Object> using Linq ASP.Net MVC - Read File from HttpPostedFileBase without save .NET NewtonSoft JSON deserialize map to a different property name Datetime in C# add days