C# 反射发射。推广Ldc_R8和Ldc_I4_0

C# 反射发射。推广Ldc_R8和Ldc_I4_0,c#,.net,reflection,metaprogramming,reflection.emit,C#,.net,Reflection,Metaprogramming,Reflection.emit,我有元程序,需要创建初始化值字段的代码。 即上课 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.Emi

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

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
}

计算堆栈操作码上是否有一些通用的负载值?或者我需要上面提到的开关?

您考虑过使用.Net表达式树吗


您是否考虑过改用.Net表达式树


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


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

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


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

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

要将变量设置为其默认值,可以使用
ldloca
后跟
initobj

initobj
通常用于结构(
default(MyStruct)
在C#)中),但它也适用于基本类型。

字段和局部变量默认都从零开始,所以您可能不需要它

要将变量设置为其默认值,可以使用
ldloca
后跟
initobj

initobj
通常用于结构(C#中的
default(MyStruct)
),但它也适用于基本类型。

当然
float
不是
R8
!你的意思是“双重”?你需要一个巨大的开关,请把它贴在你完成的地方,以便其他人可以使用:)顺便说一句,你只能处理有限的范围,我看不出编码一个大开关有什么问题。做一次,你就完成了!您不必初始化局部变量,CLR将它们初始化为0。Hans是正确的-CLR保证局部变量自动归零。因此,这些赋值毫无意义。
float
肯定不是
R8
!你的意思是“双重”?你需要一个巨大的开关,请把它贴在你完成的地方,以便其他人可以使用:)顺便说一句,你只能处理有限的范围,我看不出编码一个大开关有什么问题。做一次,你就完成了!您不必初始化局部变量,CLR将它们初始化为0。Hans是正确的-CLR保证局部变量自动归零。因此,这些赋值毫无意义。我如何使用表达式树来生成包含动态创建代码的库?@zabulus使用
CompileToMethod
-方法,但您只能将表达式编译成
静态方法。因此,您不能将其用于变量初始化。如何使用表达式树生成包含动态创建代码的库?@zabulus使用
CompileToMethod
-方法,但您只能将表达式编译为
静态方法。因此,不能将其用于变量初始化。