使用IL MethodBuilder为变量赋值

时间:2015-01-06 19:31:19

标签: c# reflection.emit

我正在构建一个继承原始类型的动态类型,并且我希望将原始类型存储在其界面中:

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,或者有没有办法让一个班级知道&#34;知道&#34;它在施工期间是基层吗?

1 个答案:

答案 0 :(得分:1)

_original是生成类型的字段。

如果要为此字段设置值,则必须:this._original = myvalue;它相当于...... ldarg_0 + [EmittedValue] + stfld(_original)。在你的情况下[EmittedValue]是一个类型:ldtoken(类型)+调用(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)