C# Cecil:获取抽象方法的实现

C# Cecil:获取抽象方法的实现,c#,.net,reflection,mono.cecil,C#,.net,Reflection,Mono.cecil,我在用塞西尔检查我的程序。除了一个例外,它工作得非常好。如何使用Cecil找到抽象方法的实现 1.要检查的代码示例 这是CallingType::CallAbstractMethod()方法调用ImplementingType::MyMethod()的代码示例 2.问题 当我使用下面的CECL代码检查我的程序时,变量myMethodDefinition表示抽象方法AbstractBase::MyMethod(),而不是ImplementingType::MyMethod()。后者是我想找到的方法

我在用塞西尔检查我的程序。除了一个例外,它工作得非常好。如何使用Cecil找到抽象方法的实现

1.要检查的代码示例 这是CallingType::CallAbstractMethod()方法调用ImplementingType::MyMethod()的代码示例

2.问题 当我使用下面的CECL代码检查我的程序时,变量myMethodDefinition表示抽象方法AbstractBase::MyMethod(),而不是ImplementingType::MyMethod()。后者是我想找到的方法。只要阅读源代码,很明显方法CallAbstractMethod实际上正在调用ImplementingType::MyMethod()

3.我的问题
如何让我的Cecil代码找到实现方法ImplementingType::MyMethod()?

CallAbstractMethod中的IL

.method public hidebysig 
    instance void CallAbstractMethod () cil managed 
{
    // Method begins at RVA 0x2078
    // Code size 15 (0xf)
    .maxstack 1
    .locals init (
        [0] class ConsoleApplication1.ImplementingType, //first variable
        [1] bool
    )

    IL_0000: nop
    IL_0001: newobj instance void ConsoleApplication1.ImplementingType::.ctor()
    IL_0006: stloc.0
    IL_0007: ldloc.0
    IL_0008: callvirt instance bool ConsoleApplication1.AbstractBase::MyMethod()
    IL_000d: stloc.1
    IL_000e: ret
} // end of method CallingType::CallAbstractMethod
正如您所看到的,callvirt操作码正在调用基类,如果您想要获得包含MyMethod实现的真实类,您必须像IL works一样使用堆栈

所以,当您运行IL_0001行时 您的堆栈将有1项,即ImplementingType的实例

然后运行IL_0006 堆栈将有0个项目,ImplementingType的实例将保存在第一个变量中

然后运行IL_0007 堆栈将再次具有1项,即ImplementingType的实例

然后运行IL_0008, 从堆栈中的第一项(即ImplementingType的实例)调用MyMethod

因此,无法仅通过行IL_0008获得对ImplementingType的引用,您必须“执行”代码、伪堆栈过程,然后才能发现包含将要执行的方法的实例

可以优化相同的代码,请参见以下内容:

.method public hidebysig 
    instance void CallAbstractMethod () cil managed 
{
    // Method begins at RVA 0x2065
    // Code size 12 (0xc)
    .maxstack 8

    IL_0000: newobj instance void ConsoleApplication1.ImplementingType::.ctor()
    IL_0005: callvirt instance bool ConsoleApplication1.AbstractBase::MyMethod()
    IL_000a: pop
    IL_000b: ret
} // end of method CallingType::CallAbstractMethod

我不知道你想用它做什么,但是你有解决方案,csprojs和c#class文件,如果你想阅读代码,我建议你使用Roslyn来完成

谢谢你详尽的回答。正如你可能猜到的,这不是我希望得到的答案。但你可能是对的。也许我必须咬紧牙关。@Pontus我知道你不想知道,这很可悲,但这是真的。你有没有考虑过使用Roslyn?和Roslyn在一起应该更容易。阅读IL仍然是可能的,但需要付出很大的努力。
.method public hidebysig 
    instance void CallAbstractMethod () cil managed 
{
    // Method begins at RVA 0x2078
    // Code size 15 (0xf)
    .maxstack 1
    .locals init (
        [0] class ConsoleApplication1.ImplementingType, //first variable
        [1] bool
    )

    IL_0000: nop
    IL_0001: newobj instance void ConsoleApplication1.ImplementingType::.ctor()
    IL_0006: stloc.0
    IL_0007: ldloc.0
    IL_0008: callvirt instance bool ConsoleApplication1.AbstractBase::MyMethod()
    IL_000d: stloc.1
    IL_000e: ret
} // end of method CallingType::CallAbstractMethod
.method public hidebysig 
    instance void CallAbstractMethod () cil managed 
{
    // Method begins at RVA 0x2065
    // Code size 12 (0xc)
    .maxstack 8

    IL_0000: newobj instance void ConsoleApplication1.ImplementingType::.ctor()
    IL_0005: callvirt instance bool ConsoleApplication1.AbstractBase::MyMethod()
    IL_000a: pop
    IL_000b: ret
} // end of method CallingType::CallAbstractMethod