将 MethodBody 转换为表达式树
有没有办法将 MethodBody (或其他反射技术)转换为 System.Linq.Expressions.Expression 树?
Is there a way to convert a MethodBody (or other Reflection technique) into a System.Linq.Expressions.Expression tree?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这确实是可能的,请参阅 DelegateDecompiler:
https://github.com/hazzik/DelegateDecompiler
注意:我是不隶属于此项目
编辑
以下是该项目采用的基本方法:
除其他外,MSIL 以及有关参数和局部变量的信息
以下是反编译方法体的项目中的代码片段:
It is indeed possible, see DelegateDecompiler:
https://github.com/hazzik/DelegateDecompiler
NOTE: I am not affiliated with this project
Edit
Here is the basic approach that the project takes:
among other things, the MSIL and info on arguments and locals
Here is a code snippet from the project that decompiles a method body:
不,没有。
您基本上是在要求 Reflector 的稍微简单的版本。
No, there isn't.
You're basically asking for a somewhat simpler version of Reflector.
是的,有可能……但据我所知,尚未实现。
您要做的困难部分是编写 CIL 反编译器。也就是说,您需要将相当低级的 CIL 指令(概念上以堆栈机为目标)转换为高级得多的表达式。
Redgate 的 Reflector 或 Telerik 的 JustDecompile 就是这样做的,但它们不是构建表达式树,而是显示源代码;你可以说它们更进一步,因为表达式树基本上仍然与语言无关。
在一些值得注意的情况下,这会变得特别棘手:
您将必须处理不存在预定义
Expression
树节点的CIL指令的情况;比如说,tail.call
,或者cpblk
(我在这里猜测一点)。也就是说,您必须创建自定义表达式树节点类型;当您.Compile()
表达式树时将它们编译回可执行方法可能是一个问题,因为表达式树编译器尝试将自定义节点分解为标准节点。如果这是不可能的,那么你就不能再编译表达式树,你只能检查它。您是否会尝试识别某些高级构造,例如 C#
using
块,并尝试为其构建一个(自定义)表达式树节点?请记住,C#using
分解为相当于try...finally { someObj.Dispose(); }
在编译期间,因此如果您通过 方法体的 CIL 指令 和 异常处理子句。因此,一般来说,您需要能够“识别”某些代码模式并将它们概括为更高级别的概念。
Yes, it is possible... but it hasn't been done yet, as far as I know.
The most difficult part of what you would have to do is write a CIL de-compiler. That is, you would need to translate the fairly low-level CIL instructions (which conceptually target a stack machine) into much higher-level expressions.
Tools such as Redgate's Reflector or Telerik's JustDecompile do just that, but instead of building expression trees, they display source code; you could say they go one step further, since expression trees are basically still language-agnostic.
Some notable cases where this would get especially tricky:
You would have to deal with cases of CIL instructions for which no pre-defined
Expression
tree node exists; let's say,tail.call
, orcpblk
(I'm guessing a little here). That is, you'd have to create custom expression tree node types; having them compiled back into an executable method when you.Compile()
the expression tree might be an issue, because the expression tree compiler tries to break down custom nodes into standard nodes. If that is not possible, then you cannot compile the expression tree any more, you could only inspect it.Would you try to recognise certain high-level constructs, such as a C#
using
block, and try to build a (custom) expression tree node for it? Remember that C#using
breaks down to the equivalent oftry…finally { someObj.Dispose(); }
during compilation, so that is what you might see instead ofusing
if you reflected over the method body's CIL instructions and exception handling clauses.Thus, in general, expect that you need to be able to "recognise" certain code patterns and summarise them into a higher-level concept.