Dynamic keyword in .NET
When I started my programming career I often heard that using
dynamic keyword should be prohibited in the context of field declaration and return types. After many years I’ve just found out that there is a good reason to use
dynamic as method return type when using reflection.
What is dynamic?
As many static typed languages C# requires to define a type for almost everything. Every type must be known at compile time. C# 4 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. The code is valid at runtime, but any unforeseen errors are handled in runtime. When using
System.Reflection most of the types are
dynamic until casting occures.
The problem: finding a implementation
For our problem in question let’s imagine we are trying to implement an action handler for any action that is implementing
IAction interface. We don’t want to register handlers for each and every action in one, central module but rather find corresponding type dynamically through reflection mechanizm in .NET. Let’s also define our action handler interface as follows:
public interface IActionHandler<in TAction> where TAction : IAction
void Execute(TAction action);
Let’s also assume that our data comes from simple text file so we don’t really know what action we are suppose to run until we are at runtime. To initialize action we’ll use
Activator.CreateInstance. That allows us to create an instance of a type dynamically without using the type explicitly, e.g. like in one big switch statement. For using handler there is a static
HandlerProvider implementation which selects type from correct assembly.
public static Type GetHandler<THandler>()
// ReSharper disable once PossibleNullReferenceException
.SingleOrDefault(x => typeof(THandler).IsAssignableFrom(x));
Casting action to an interface
Let’s try getting handler for our
SampleAction by casting an action to derived interface. This can be done because
Activator creates an instance of provided type which is implementing
private static IAction GetAction()
private static Type GetHandler<TAction>(TAction action)
where TAction : IAction
In this case we cannot find action handler because provider is looking for generic implementation of
IActionHandler<IAction> and there isn’t any. Through casting dynamic type to implemented interface we have lost irreversibly our original type of
Using dynamic type as method return type
What happens if we switch from casting our
dynamic type do an interface and just leaving it
dynamic? Let’s change
GetAction definition to
private static dynamic GetAction()
Now we are using dynamic as return type therefore it’s not handled as
IAction but rather as a proper instance of
SampleAction type. It can be seen while debugging
GetHandler entry point. .NET actually uses
System.Runtime.CompilerServices to manage types at runtime so that the type is initialized.
You can look at entire code here: mszynka@github/dynamic-type-checking