Search code examples
c#stringdynamicexpression-treesdynamic-language-runtime

Why does string concatenation with the + operator work with dynamic types in C#?


I recently saw an example where the following was demonstrated to work:

T Add<T>(dynamic a, dynamic b)
{
    return a + b;
}

Add<string>("hello", "world");  // Returns "helloworld"

However, if I were to attempt to use expressions to create a "generic" Add function:

ParameterExpression left = Expression.Parameter(typeof(T), "left");
ParameterExpression right = Expression.Parameter(typeof(T), "right");
var add = Expression.Lambda<Func<T, T, T>>(Expression.Add(left, right), left, right).Compile();  // Fails with System.InvalidOperationException : The binary operator Add is not defined for the types 'System.String' and 'System.String' when T == String.

and then used this function with strings, it fails because the String type does not actually implement the + operator, but is simply syntactic sugar for String.Concat().

How then, does dynamic allow this to work? I figured that at runtime it is past the point where + would be rewritten using String.Concat().


Solution

  • dynamic uses runtime helper functions that replicate C# compiler rules. One of these rules allows + on string objects even when no operator is defined by the framework. The standard numeric types such as int have no custom operator overload either, that too is done by the compiler and needs to be performed at runtime when using dynamic. This is why you need a reference to Microsoft.CSharp.dll: dynamic cannot work without those helper functions.