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().
dynamicuses runtime helper functions that replicate C# compiler rules. One of these rules allows+onstringobjects even when no operator is defined by the framework. The standard numeric types such asinthave no custom operator overload either, that too is done by the compiler and needs to be performed at runtime when usingdynamic. This is why you need a reference to Microsoft.CSharp.dll:dynamiccannot work without those helper functions.