The dynamic
keyword is used with dynamically typed objects. Objects declared as dynamic
forego compile-time static checks, and are instead evaluated at runtime.
using System;
using System.Dynamic;
dynamic info = new ExpandoObject();
info.Id = 123;
info.Another = 456;
Console.WriteLine(info.Another);
// 456
Console.WriteLine(info.DoesntExist);
// Throws RuntimeBinderException
The following example uses dynamic
with Newtonsoft's library Json.NET, in order to easily read data from a deserialized JSON file.
try
{
string json = @"{ x : 10, y : ""ho""}";
dynamic deserializedJson = JsonConvert.DeserializeObject(json);
int x = deserializedJson.x;
string y = deserializedJson.y;
// int z = deserializedJson.z; // throws RuntimeBinderException
}
catch (RuntimeBinderException e)
{
// This exception is thrown when a property
// that wasn't assigned to a dynamic variable is used
}
There are some limitations associated with the dynamic keyword. One of them is the use of extension methods. The following example adds an extension method for string: SayHello
.
static class StringExtensions
{
public static string SayHello(this string s) => $"Hello {s}!";
}
The first approach will be to call it as usual (as for a string):
var person = "Person";
Console.WriteLine(person.SayHello());
dynamic manager = "Manager";
Console.WriteLine(manager.SayHello()); // RuntimeBinderException
No compilation error, but at runtime you get a RuntimeBinderException
. The workaround for this will be to call the extension method via the static class:
var helloManager = StringExtensions.SayHello(manager);
Console.WriteLine(helloManager);