C# Cecil-如何获取方法体的简单示例

C# Cecil-如何获取方法体的简单示例,c#,reflection,system.reflection,mono.cecil,C#,Reflection,System.reflection,Mono.cecil,我一直在寻找一个新手问题,但找不到一个简单的例子。 谁能给我一个简单的例子,如何将MethodBody转换成最可用的字符串结果?比如: using Mono.Cecil; using Mono.Cecil.Cil; namespace my { public class Main { public Main() { // phseudo code, but doesnt work Console.

我一直在寻找一个新手问题,但找不到一个简单的例子。 谁能给我一个简单的例子,如何将MethodBody转换成最可用的字符串结果?比如:

using Mono.Cecil;
using Mono.Cecil.Cil;

namespace my
{
    public class Main
    {
        public Main()
        {
             // phseudo code, but doesnt work
            Console.Write(    getMethod("HelloWorld").GetMethodBody().ToString()   );
        }

        public void HelloWorld(){
             MessageBox.Show("Hiiiiiiiiii");
        }
    }
}

从阅读程序集开始:

var path = "... path to your assembly ...";
var assembly = AssemblyDefinition.ReadAssembly(path);
如果要打开正在运行的进程,可以将
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
用作
path

现在获取您要检查的所有类型和方法

var toInspect = assembly.MainModule
  .GetTypes()
  .SelectMany(t => t.Methods
      .Where(m => m.HasBody)
      .Select(m => new {t, m}))
  
如果您已经知道类型和方法名称,可以修改查询,如下所示:

toInspect = toInspect.Where(x => x.t.Name.EndsWith("Main") && x.m.Name == "HelloWorld");
之后,只需迭代该集合:

foreach (var method in toInspect)
{
    Console.WriteLine($"\tType = {method.t.Name}\n\t\tMethod = {method.m.Name}");
    foreach (var instruction in method.m.Body.Instructions)
        Console.WriteLine($"{instruction.OpCode} \"{instruction.Operand}\"");
}
输出将是

Type = Main
  Method = HelloWorld

ldstr "Hiiiiiiiiii"
call "System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(System.String)"
pop ""
ret ""

您需要或期望什么样的字符串结果?十六进制字节码?人类可读的IL指令@他们说,我希望人类可读。我知道它不会100%完美,但无论最大值是多少。ildasm是一个选项吗?否则,您应该找到一些如何使用mono.cecil获取方法体的代码。从那里你可以循环使用
指令
-对象,我想它们支持
ToString()
@thehennyMate,这就是我要问的。我找不到,这就是为什么我在这里问——我不是C#pro.Aleks,非常感谢你的出色回答,我已经投票并在时间上做了标记。但是,我的问题是,当您定义
检查
对象时(因此,不使用“selectMany&where”命令),您能给我一个不使用linq的版本吗?谢谢