3
有没有办法使用System.CodeDom
或Roslyn API来解决代码中的重载方法调用?在运行时,我有一个方法名和一个参数列表,我想找到编译器在编译时选择的方法。以编程方式执行重载解决方案
有没有办法使用System.CodeDom
或Roslyn API来解决代码中的重载方法调用?在运行时,我有一个方法名和一个参数列表,我想找到编译器在编译时选择的方法。以编程方式执行重载解决方案
由于@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
一旦你有了答案,你会怎么做?另外,你的参数列表是什么形式? – 2014-10-20 22:29:55
@JasonMalinowski我的参数列表是一个类型数组。我正在寻找一种方法来强制VB中的运行时方法绑定来解决[此问题](http://stackoverflow.com/q/26470484/794234)。我可以编写代码来自己执行解析(w/reflection),但规则很复杂,重新发明轮子似乎很愚蠢。 – 2014-10-21 06:30:01
我想知道是否可以直接使用'dynamic'基础设施来执行此操作。 – SLaks 2014-10-21 12:13:44