Perform programmatic conversion
As @SLaks and @ just.another.programmer suggested that C # dynamic framework could be used. But it is really not easy and not easy. I looked at the decompiled code for a couple of hours to find the following magic code. And I don't fully understand it. In the first step, a class is created Binder
, with parameters set to use compile-time types.
This second magic step binder is called parameters. Each parameter has its own value (null, it is not used when set UseCompileTimeType
) and their expression. If you know types instead of expressions, use Expression.Parameter(yourType)
them to replace them.
public static Expression GetInvokeMemberExpression(Expression expr, string name, Expression[] arguments)
{
var type = expr.Type;
var argTypes = arguments.Select(e => e.Type).ToArray();
// do magic #1
var binder = (DynamicMetaObjectBinder)Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
CSharpBinderFlags.None, name,
Type.EmptyTypes, // type arguments
typeof(object),
Enumerable.Repeat(0, argTypes.Length + 1).Select(_ => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)).ToArray());
// do magic #2
var result = binder.Bind(DynamicMetaObject.Create(null, expr), arguments.Select(a => DynamicMetaObject.Create(null, a)).ToArray());
var resultMethodCall = (result.Expression as UnaryExpression).Operand as MethodCallExpression; // unwrap convert to ebject expression
var method = resultMethodCall.Method;
return resultMethodCall;
}
I tried to use a similar piece of code in the DotVVM framework , but I couldn't find a way to "inject" custom implicit conversions, so I wrote a simple method overload recognition function. But we still use dynamic for operators. You can find the code on github
source to share