【问题标题】:Reflection Emit. Generalizing Ldc_R8 and Ldc_I4_0反射发射。概括 Ldc_R8 和 Ldc_I4_0
【发布时间】:2012-02-18 23:48:46
【问题描述】:

我有元程序,需要创建用于初始化值字段的代码。 IE。上课

class Class1
{
    int i;
    double t;
    Class1()
    {
       i=5;
       t=3;
    }
} 

反思如下:

...
gen.Emit(OpCodes.Ldc_I4,5);
...
gen.Emit(OpCodes.Ldc_R8,3);
...

我不想有这样一个巨大的开关:

switch(t)
{
case typeof(int): gen.Emit(OpCode.Ldc_I4,value); break;
case typeof(double): gen.Emit(OpCodes.Ldc_R8,value); break;
// and so on for all value types
}

评估堆栈 OpCode 上是否有一些通用负载值?或者我需要上面提到的开关?

【问题讨论】:

  • 肯定float 不是R8!你的意思是double
  • 你需要这个巨大的开关,请把它贴在你完成的地方,以便其他人可以使用它:)
  • 顺便说一句,你只有一个有限的范围来处理,我没有看到编码一个大开关的问题。做一次,你就完成了!
  • 你不必初始化局部变量,CLR将它们初始化为0。
  • Hans 是对的——CLR 保证局部变量自动归零。因此,这些作业根本没有意义。

标签: c# .net reflection metaprogramming reflection.emit


【解决方案1】:

【讨论】:

  • 如何使用表达式树来生成包含动态创建代码的库?
  • @zabulus 使用CompileToMethod-方法,但您只能将表达式编译成static 方法。所以你不能用它来初始化变量。
【解决方案2】:

默认情况下,字段和局部变量都从零开始,因此您可能不需要它。

要将变量设置为其默认值,您可以使用ldloca <variable>,后跟initobj <type>initobj 通常用于结构(C# 中的default(MyStruct)),但它也适用于原始类型。

【讨论】:

    【解决方案3】:

    没有内置这样的方法。您可以自己创建一个助手,并始终解决问题。

    也就是说,您可以使用表达式树并将发出代码放入您选择的 ILGenerator 中。这意味着您不仅可以生成动态方法,还可以使用它们来填充 TypeBuilder 创建的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多