简体   繁体   中英

Get member definition from reference in Mono.Cecil

I noticed that the field or method references in certain types of methods (a method in a generic type for example) will be of FieldReference type, not FieldDefinition although the field (or the method) is in the same module, in the same type. How can I get the FieldDefinition from this FieldReference ?

I tried module.Import and module.MetadataResolver.Resolve but both don't work.

A follow up to this question, but a more general one.

EDIT:

A simple generic class:

public class HelperClass<T>
{
    private int _someInt;

    void SomeMethod(int i)
    {
        _someInt = i;
    }
}

SomeMethod 's body contains:

...
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: stfdl System.Int32 HelperClass`1<T>::_someInt
....

The IL_000a opcode's operand is supposed to be a FieldDefinition normally, after all it's in the same module. But because HelperClass is generic I suppose, the operand is a FieldReference that won't resolve, I can just hope to compare the fullnames to actually find the FieldDefinition .

In this case this is not big of a problem, but it is when the reference is to other members in other generic types, I'm sure there's a better way to do it than enumerating through all the types to find the definition.

EDIT:

The HelperClass<> is from a module that is loaded at runtime by AssemblyDefinition.ReadAssembly , that's when the .Resolve() returns null instead of returning the FieldDefinition .

UPDATE:

It turned out that because I'm changing the name of the field in the generic type, the reference is breaking and Resolve() is returning null. Still on look for a decent solution for this one .

Update:

I've changed the code to separate types into different projects in different solutions. Unfortunately, I'm still not able to reproduce the issue, but I'm willing to keep trying if it will help.

I'm able to resolve the type reference with the following code. If you are able to provide more details for a reproduction, I'd be willing to take another crack at this :-)

This is the only type in an assembly called TargetLibrary.dll. I compiled it in its own solution, and copied the assembly into C:\\Temp .

public class HelperClass<T>
{
    private int _someInt;

    void SomeMethod(int i)
    {
        _someInt = i;
    }
}

This code is in a different assembly, which is compiled into a console exe file within its own solution.

class Program
{
    static void Main(string[] args)
    {
        var module = AssemblyDefinition.ReadAssembly(@"C:\Temp\TargetLibrary.dll").MainModule;

        Console.WriteLine("For HelperClass<>");
        var helperClass = module.Types[1];
        var someMethod = helperClass.Methods[0];
        var someMethodBody = someMethod.Body;
        foreach (var instruction in someMethodBody.Instructions)
        {
            Console.WriteLine(
                "{0}\t{1}\t{2}",
                instruction.Offset,
                instruction.OpCode.Code,
                instruction.Operand == null ? "<null>" : string.Format("{0} / {1}", instruction.Operand.GetType().FullName, instruction.Operand.ToString()));

            var fieldReference = instruction.Operand as FieldReference;
            if (fieldReference != null)
            {
                var fieldDefinition = fieldReference.Resolve();
                Console.WriteLine(
                    "\t\tResolved field reference operand: {0} / {1}",
                    fieldDefinition.GetType().FullName,
                    fieldDefinition.ToString());
            }
        }
    }
}

Running this produces the following output.

For HelperClass<>
0       Ldarg_0 <null>
1       Ldarg_1 <null>
2       Stfld   Mono.Cecil.FieldReference / System.Int32 TargetLibrary.HelperClass`1<T>::_someInt
                Resolved field reference operand: Mono.Cecil.FieldDefinition / System.Int32 TargetLibrary.HelperClass`1::_someInt
7       Ret     <null>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM