Mono.Cecil: call base class' method from other

2019-07-02 02:55发布

问题:

How can I get a MethodReference to a base class' method by name?

I've tried

type.BaseType.Resolve().Methods;

and if I add the dll containing the base class to the assemblyresolver it returns the methods. But if I add a call using

MSILWorker.Create(OpCodes.Call, baseMethod);

(where baseMethod was found by foreaching Methods from the resolved TypeDefinition) the resulting IL is unreadable, even Reflector freezes and quits.

Now some IL:
if calling private method on type:

 call instance void SomeNamespace.MyClass::RaisePropertyChanged(string)

if calling protected method on base type:

call instance void [OtherAssembly]BaseNamespace.BaseClass::RaisePropertyChanged(string)

So, how can I produce the latter using Mono.Cecil?

回答1:

As you guessed, you need to get a proper MethodReference scoped for the module. So if you have:

TypeDefinition type = ...;
TypeDefintion baseType = type.BaseType.Resolve ();
MethodDefinition baseMethod = baseType.Methods.First (m => ...);

Then baseType and baseMethod are definitions from another module. You need to import a reference to the baseMethod before using it:

MethodReference baseMethodReference = type.Module.Import (baseMethod);
il.Emit (OpCodes.Call, baseMethodReference);