Perform programmatic conversion

Is there a way to use either the System.CodeDom

Roslyn API to resolve overloaded method call from code? At runtime I have a method name and a list of parameters, I want to find the method the compiler would choose at compile time.

+3


source to share


1 answer


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

0


source







All Articles