C# Cecil:获取抽象方法的实现
我在用塞西尔检查我的程序。除了一个例外,它工作得非常好。如何使用Cecil找到抽象方法的实现 1.要检查的代码示例 这是CallingType::CallAbstractMethod()方法调用ImplementingType::MyMethod()的代码示例 2.问题 当我使用下面的CECL代码检查我的程序时,变量myMethodDefinition表示抽象方法AbstractBase::MyMethod(),而不是ImplementingType::MyMethod()。后者是我想找到的方法。只要阅读源代码,很明显方法CallAbstractMethod实际上正在调用ImplementingType::MyMethod() 3.我的问题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代码找到实现方法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