C# Dynamic

The dynamic keyword influences compilation. A dynamic variable, parameter or field can have any type. Its type can change during runtime. The downside is that performance suffers and you lose compile-time checking.

Dynamic keyword

This C# article reveals how to use the dynamic keyword. Example C# code and IL is provided.

Example

Note

The dynamic keyword is used to replace other types such as int, bool or string. In this example, we assign the value 1 to the dynamic variable a. This means "a" is of type System.Int32 at that point. Next, we assign it to a string array; the type again changes. You can also use dynamic as a return type (or formal parameter type). Finally, we use a dynamic static field, and call a non-existent property on it.

Program that uses dynamic type [C#, .NET 4.0]

using System;

class Program
{
    static dynamic _y;

    static void Main()
    {
	// Use dynamic local.
	dynamic a = 1;
	Console.WriteLine(a);

	// Dynamic now has a different type.
	a = new string[0];
	Console.WriteLine(a);

	// Assign to dynamic method result.
	a = Test();
	Console.WriteLine(a);

	// Use dynamic field.
	_y = "carrot";

	// You can call anything on a dynamic variable,
	// ... but it may result in a runtime error.
	Console.WriteLine(_y.Error);
    }

    static dynamic Test()
    {
	return 1;
    }
}

Output

1
System.String[]
1

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
    'string' does not contain a definition for 'Error'...

Non-existent members. The compiler allows you to call non-existent properties, fields and methods on a variable of type dynamic. You can see that the field _y is clearly a string, but there is no Error property on String. This results in a run-time, not compile-time, error.

Dynamic Expression. In Visual Studio 2010, try hovering over the "WriteLine" method call in the program. You will see it displays "(dynamic expression) This operation will be resolved at runtime." This means you are not actually calling WriteLine directly! Instead, you are calling something named WriteLine at runtime and passing it one argument. Before you compile the program, who knows what will happen.

How does it work?

Question and answer

The dynamic keyword is implemented with a lot of compile-time transformations by the C# compiler. You won't find any "dynamic" types in the low-level virtual execution engine. Instead, the C# compile builds up an alternate representation of your dynamic code and then outputs that to the metadata.

Looking at the intermediate language, we can see that the dynamic keyword results in a custom class being generated by the compiler. This class is contains fields for each of the "sites" where dynamic is used.

Code generated for above example [C#]

[CompilerGenerated]
private static class <Main>o__SiteContainer0
{
    // Fields
    public static CallSite<Action<CallSite, Type, object>> <>p__Site1;
    public static CallSite<Action<CallSite, Type, object>> <>p__Site2;
    public static CallSite<Action<CallSite, Type, object>> <>p__Site3;
}

Next, we can look at the call sites themselves. At each call site, the site field from the above static class is instantiated if it hasn't already been. Then, the Target method on the site field is called. The method "WriteLine" is specified as a string. The class we are calling (Console) is specified as a Type pointer with typeof.

Typeof Operator
Code generated at call sites [C#]

if (<Main>o__SiteContainer0.<>p__Site1 == null)
{
    <Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, Type, object>>.Create(
	Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "WriteLine", null,
	typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(
	CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,
	null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
}
<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1,
    typeof(Console), a);

Type

The dynamic keyword is used as a type in the C# language, but it is not a type in the underlying intermediate language. Thus, it can be considered a high-level type but not a low-level type. Most constructs in the C# language correspond fairly closely to their underlying representation. Other exceptions to this rule include the yield return construct and the params keyword.

Yield Return Example Params Method

Practical use

Programming tip

It is definitely a bad idea to use dynamic in all cases where it can be used. This is because your programs will lose the benefits of compile-time checking and they will also be much slower. (All the code generated by the C# compiler would yield a program that is many times slower than a regular C# program.)

Compile-Time Error

Uses. There are some uses of dynamic currently. It can make poorly-designed external libraries easier to use: Microsoft provides the example of the Microsoft.Office.Interop.Excel assembly. With dynamic, you can avoid a lot of annoying, explicit casting.

Excel Interop: Microsoft.Office.Interop.Excel

Summary

The C# programming language

The dynamic keyword in the C# language provides access to the Dynamic Language Runtime, which is an additional layer of functionality on top of the Common Language Runtime. This basically means dynamic is implemented with a lot of inserted code that simply uses the CLR. This advanced functionality can be useful in certain situations but, when it is used, erases many of the benefits of the C# language.

Method Tips
.NET