2014-10-20 62 views
3

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

+0

一旦你有了答案,你会怎么做?另外,你的参数列表是什么形式? – 2014-10-20 22:29:55

+0

@JasonMalinowski我的参数列表是一个类型数组。我正在寻找一种方法来强制VB中的运行时方法绑定来解决[此问题](http://stackoverflow.com/q/26470484/794234)。我可以编写代码来自己执行解析(w/reflection),但规则很复杂,重新发明轮子似乎很愚蠢。 – 2014-10-21 06:30:01

+1

我想知道是否可以直接使用'dynamic'基础设施来执行此操作。 – SLaks 2014-10-21 12:13:44

回答

0

由于@SLaks和@ just.another.programmer建议可以利用C#动态基础结构。但这并不简单也不简单。我正在注视反编译的代码几个小时,以找到以下的魔法代码。我完全不理解它。在第一步中,创建类Binder,并将参数选项设置为使用编译时类型。

它的第二个魔术步骤活页夹被参数调用。每个参数都有其值(空,当设置为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

相关问题