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