我注意到某些类型的方法中的字段或方法引用(例如,泛型类型中的方法)将是FieldReference
类型,而不是FieldDefinition
,尽管字段(或方法)在同一模块中,属于同一类型。如何从此FieldDefinition
获取FieldReference
?
我尝试了module.Import
和module.MetadataResolver.Resolve
,但两人都没有工作。
this问题的后续问题,但更为一般。
修改
一个简单的通用类:
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
,我只希望比较全名来实际找到FieldDefinition
。
在这种情况下,这不是一个大问题,但是当引用其他泛型类型的其他成员时,我确定有更好的方法来实现它而不是枚举所有的找到定义的类型。
修改
HelperClass<>
来自AssemblyDefinition.ReadAssembly
在运行时加载的模块,当.Resolve()
返回null而不是返回FieldDefinition
时。{ / p>
更新
事实证明,因为我更改了泛型类型中字段的名称,引用正在中断,Resolve()
返回null。仍在寻找this one的合适解决方案。
答案 0 :(得分:1)
更新
我已经将代码更改为在不同的解决方案中将类型分成不同的项目。不幸的是,我仍然无法重现这个问题,但我愿意继续尝试,如果有帮助的话。
我可以使用以下代码解析类型引用。如果您能够提供更多有关复制的详细信息,我愿意接受另一个问题: - )
这是名为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>