繁体   English   中英

从Mono.Cecil中的引用获取成员定义

[英]Get member definition from reference in Mono.Cecil

我注意到,某些类型的方法(例如,通用类型的方法)中的字段或方法引用将是FieldReference类型,而不是FieldDefinition尽管该字段(或方法)在同一模块中,并且是同一类型。 我怎样才能获得FieldDefinition从这个FieldReference

我试图module.Importmodule.MetadataResolver.Resolve但都不起作用。

这个问题的跟进,但更为笼统。

编辑:

一个简单的通用类:

public class HelperClass<T>
{
    private int _someInt;

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

SomeMethod的主体包含:

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

IL_000a操作码的操作数应为FieldDefinition ,毕竟它在同一模块中。 但由于HelperClass是通用的,我想,该操作数是一个FieldReference不会解决,我只希望比较fullnames真正找到FieldDefinition

在这种情况下,这并不是什么大问题,但是这是当引用其他通用类型中的其他成员时,我敢肯定有比枚举所有类型来查找定义更好的方法。

编辑:

HelperClass<>来自于在运行时由AssemblyDefinition.ReadAssembly加载的模块,那时.Resolve()返回null而不是返回FieldDefinition

更新:

事实证明,由于我要更改通用类型中的字段名称,因此引用已断开,并且Resolve()返回null。 仍然在寻找一个体面的解决方案这一个

更新:

我更改了代码,以将类型分为不同解决方案中的不同项目。 不幸的是,我仍然无法重现该问题,但我愿意继续尝试是否有帮助。

我可以使用以下代码来解析类型引用。 如果您能够提供更多复制品的详细信息,那么我愿意在此另辟crack径:-)

这是程序集中名为TargetLibrary.dll的唯一类型。 我在自己的解决方案中对其进行了编译,然后将该程序集复制到C:\\Temp

public class HelperClass<T>
{
    private int _someInt;

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

此代码在不同的程序集中,该程序集在其自己的解决方案中编译为控制台exe文件。

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());
            }
        }
    }
}

运行此命令将产生以下输出。

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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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