1

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

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 方法并调用该方法,但如果不将其转换为 Delegate,我没有找到一种方法来执行此操作,这会生成大量样板代码。

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

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

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

我正在尝试从基于堆栈的 vm 字节码到 CIL 制作一种“重新编译器”。有问题的字节码不像 CIL 那样访问结构中的字段,即静态访问。相反,对要访问的字段的引用被压入堆栈,store其余的由指令处理。

以下是此字节码的示例:

PushFloat 0.0
PushField [someField]
SetField

我想要获得的是类似于我上面编写的代码,但 CIL 仅支持分配给在代码生成时已知的字段。

4

1 回答 1

1

我已经通过使用ldfldaand解决了这个问题stind

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

这似乎在做我最初打算做的事情。

于 2020-02-17T16:17:35.260 回答