以编程方式执行重载决策

时间:2014-10-20 19:39:48

标签: vb.net overloading codedom roslyn

有没有办法使用System.CodeDom或Roslyn API来解析代码中的重载方法调用?在运行时,我有一个方法名和一个参数列表,我想找到编译器在编译时选择的方法。

1 个答案:

答案 0 :(得分:0)

正如@SLaks和@ just.another.programmer所建议的,可以利用C#动态基础架构。但它真的不是直截了当也不简单。我正在注意反编译的代码几个小时,以找到以下魔法代码。而且我完全不了解它。在第一步中创建了Binder类,并将参数选项设置为使用编译时类型。

使用参数调用第二个魔术步骤绑定器。每个参数都有其值(null,设置UseCompileTimeType时不使用)及其表达式。如果您知道类型而不是表达式,请使用Expression.Parameter(yourType)替换它们。

    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;
    }

我在DotVVM framework尝试了类似的代码,但我还没有找到一种如何注入""自定义隐式转换,所以我写了一个简单的方法重载识别函数。但我们仍在为运营商使用动态。 You can find the code on github