有没有办法将 MethodBody(或其他反射技术)转换为 System.Linq.Expressions.Expression 树?
3 回答
确实有可能,见 DelegateDecompiler:
https://github.com/hazzik/DelegateDecompiler
注意:我不隶属于这个项目
编辑
以下是该项目采用的基本方法:
- 获取要转换的方法的 MethodInfo
- 使用 methodInfo.GetMethodBody 获取 MethodBody 对象。其中包含 MSIL 以及有关参数和本地信息的信息
- 仔细阅读说明,检查操作码,并构建适当的表达式
- 将它们捆绑在一起并返回优化的表达式
这是项目中反编译方法体的代码片段:
public class MethodBodyDecompiler
{
readonly IList<Address> args;
readonly VariableInfo[] locals;
readonly MethodInfo method;
public MethodBodyDecompiler(MethodInfo method)
{
this.method = method;
var parameters = method.GetParameters();
if (method.IsStatic)
args = parameters
.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name))
.ToList();
else
args = new[] {(Address) Expression.Parameter(method.DeclaringType, "this")}
.Union(parameters.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name)))
.ToList();
var body = method.GetMethodBody();
var addresses = new VariableInfo[body.LocalVariables.Count];
for (int i = 0; i < addresses.Length; i++)
{
addresses[i] = new VariableInfo(body.LocalVariables[i].LocalType);
}
locals = addresses.ToArray();
}
public LambdaExpression Decompile()
{
var instructions = method.GetInstructions();
var ex = Processor.Process(locals, args, instructions.First(), method.ReturnType);
return Expression.Lambda(new OptimizeExpressionVisitor().Visit(ex), args.Select(x => (ParameterExpression) x.Expression));
}
}
不,没有。
您基本上是在要求一个更简单的Reflector版本。
是的,有可能……但据我所知,还没有完成。
如果有人知道将方法反编译为表达式树的库,请告诉我,或编辑上述语句。
您要做的最困难的部分是编写CIL反编译器。也就是说,您需要将相当低级的 CIL 指令(在概念上以堆栈机器为目标)转换为更高级别的表达式。
Redgate的Reflector或 Telerik 的JustDecompile等工具就是这样做的,但它们不是构建表达式树,而是显示源代码;您可以说它们更进一步,因为表达式树基本上仍然与语言无关。
一些值得注意的情况会变得特别棘手:
您将不得不处理不存在预定义
Expression
树节点的 CIL 指令的情况;比方说,tail.call
或cpblk
(我在这里猜一点)。也就是说,您必须创建自定义表达式树节点类型;当您使用表达式树时,将它们编译回可执行方法.Compile()
可能是一个问题,因为表达式树编译器会尝试将自定义节点分解为标准节点。如果那不可能,那么您将无法再编译表达式树,您只能检查它。您会尝试识别某些高级构造(例如 C#
using
块)并尝试为其构建(自定义)表达式树节点吗?请记住,C#在编译期间using
分解为等价物try…finally { someObj.Dispose(); }
,因此您可能会看到这种情况,而不是using
反映在方法主体的 CIL 指令和异常处理子句中。因此,一般来说,期望您能够“识别”某些代码模式并将它们总结为更高级别的概念。