使用 IL MethodBuilder 为变量赋值

本文关键字:变量 赋值 MethodBuilder IL 使用 | 更新日期: 2023-09-27 18:36:24

我正在构建一个继承自原始类型的动态类型,我想将原始类型存储在它的界面中:

public interface IInterface
{
    Type OriginalType { get; }
}

所以我可以在需要时使用原始类型,而不是动态创建的类型。

FieldBuilder _original = typeBuilder.DefineField("_original", typeof(Type), FieldAttributes.Private);
PropertyInfo originalProperty = typeof(IProxy).GetProperty("OriginalType");
// - Building the getProperty, omitted for brevity
// - Then, during the constructors construction:
foreach (ConstructorInfo constructorInfo in typeBuilder.BaseType.GetConstructors())
{
    // - Parameters, omitted
    ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, parameters);
    ILGenerator ilGen = constructorBuilder.GetILGenerator();
    // - I want to assign a variable to the local '_original' with a value I have present at this moment
    // - This doesn't work!
    ilGen.Emit(OpCodes.Ldtoken, typeBuilder.BaseType);
    ilGen.Emit(OpCodes.Ldfld, _original);
    // - Calling the original constructor   
    ilGen.Emit(OpCodes.Ldarg_0);
    for (int i = 1; i <= parameters.Length; i++)
    { ilGen.Emit(OpCodes.Ldarg_S, i); }
    ilGen.Emit(OpCodes.Call, constructorInfo);
    ilGen.Emit(OpCodes.Ret);
}

如何分配这样的值?是否有特定的OpCode,或者是否有一种方法可以让类在构造过程中"知道"它是基类?

使用 IL MethodBuilder 为变量赋值

_original是

生成类型的字段。

如果要为此字段设置值,则必须: this._original = myvalue; 它等效于...ldarg_0 + [EmittedValue] + stfld(_original).在你的情况下 [EmittedValue] 是一个类型:ldtoken(type) + call(Type.GetTypeFromHandle)

ldarg_0 //this
ldtoken //typehandle
call Type.GetTypeFromHandle //TypeHandle to Type
stfld _original //setfield (must be follow ldarg_0 and value as Type)