动态分配字段

Dynamically assign a field

我正在尝试生成用于将字段值动态分配给动态 class 的代码。基本上,我理想情况下能够做的就是达到这种效果:

il.Emit(OpCodes.Ldarg_0); // Object instance
il.Emit(OpCodes.Ldc_I4_0); // Value to assign to the field
il.Emit(OpCodes.Ld???, fieldInfo); // FieldInfo to assign the value to
il.Emit(OpCodes.Stfld); // Some kind of Stfld that pops the field and the value and assigns it

我找不到任何适合我需要的说明。我的另一个想法是为每个字段生成一个 setter 方法并调用该方法,但我没有找到一种方法来执行此操作而不将其转换为委托,它生成了 很多 样板代码。

有没有人有更好的解决方案?

编辑: 问题是需要分配的字段必须在堆栈中找到,并且在分配它的时候以某种方式弹出。不幸的是,none 的 CIL 指令支持弹出一个 fieldInfo 以分配给它,但也许还有其他我没有想到的解决方案。

EDIT2:我会给出更多的周围场景,希望上下文能让事情更清楚。

我正在尝试从基于堆栈的 vm 字节码到 CIL 进行某种 "recompiler"。有问题的字节码不像 CIL 那样访问结构中的字段,即静态访问。相反,对要访问的字段的引用被压入堆栈,store 指令负责其余部分。

下面是这个字节码的示例:

PushFloat 0.0
PushField [someField]
SetField

我想得到的是我上面写的代码,但 CIL 只支持分配给代码生成时已知的字段。

我已经使用 ldfldastind 解决了这个问题:

il.Emit(OpCodes.Ldarg_0); // Object instance
il.Emit(OpCodes.Ldflda, fieldInfo); // Loads reference to field
il.Emit(OpCodes.Conv_U); // Converts to pointer
il.Emit(OpCodes.Ldc_I4_0); // Something to put in the field
il.Emit(OpCodes.Stind_I4); // Put the value in the field

这似乎与我最初打算做的大致相同。