mardi 15 décembre 2015

Mono.Cecil: get implementation of abstract method

I'm using Cecil to inspect my code. It is working really great with one exception. How can I use Cecil to find the implementation of an abstract method?

1. Example of code to inspect

This is an example of code where the method CallingType::CallAbstractMethod() makes a call to ImplementingType::MyMethod().

public abstract class AbstractBase
{
    public abstract bool MyMethod();
}

public class ImplementingType : AbstractBase
{
    public override bool MyMethod()
    {
        return true;
    }
}

public class CallingType
{
    public void CallAbstractMethod()
    {
        var implementingType = new ImplementingType();
        var result = implementingType.MyMethod();
    }
}

2. My problem

When I use the Cecil code below to inspect my program the variable myMethodDefinition represents the abstract method AbstractBase::MyMethod() instead of ImplementingType::MyMethod(). The later is the method that I would like to find. Just reading the source it is obvious that the method CallAbstractMethod is actually calling ImplementingType::MyMethod().

var assembly = AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location);

var callingType = assembly.MainModule.Types
    .Single(t => t.Name == "CallingType");

var callAbstractMethodDefinition = callingType.Methods
    .Single(m => m.Name == "CallAbstractMethod");

var myMethodReference = callAbstractMethodDefinition.Body.Instructions
    .Where(i => i.OpCode == OpCodes.Callvirt)
    .Select(i => (MethodReference)i.Operand)
    .Single();

var myMethodDefinition = myMethodReference.Resolve();

3. My question

What can I do to get my Cecil code to find the implementing method ImplementingType::MyMethod()?





Aucun commentaire:

Enregistrer un commentaire