Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Msil以动态类型发出静态数组_C#_Arrays_Static_Cil_Reflection.emit - Fatal编程技术网

C# Msil以动态类型发出静态数组

C# Msil以动态类型发出静态数组,c#,arrays,static,cil,reflection.emit,C#,Arrays,Static,Cil,Reflection.emit,我正在尝试使用Reflection.Emit(在c#中)创建一个新类型 我想要创建的代码类似于 public class { public static int[] A = new int[] {1, 2, 3}; } 我首先尝试定义一个字段,然后设置其值: var fb = tb.DefineField("A", FieldAttributes.Public | FieldAttributes.Static); fb.SetValue(null, new int[] {1, 2, 3

我正在尝试使用Reflection.Emit(在c#中)创建一个新类型

我想要创建的代码类似于

public class 
{
   public static int[] A = new int[] {1, 2, 3};
}
我首先尝试定义一个字段,然后设置其值:

var fb = tb.DefineField("A", FieldAttributes.Public | FieldAttributes.Static);
fb.SetValue(null, new int[] {1, 2, 3});
但它不起作用,因为setValue只支持简单类型(int、float等)

现在我尝试使用DefineInitializedData(长得多的代码,不起作用…),但它不会生成任何有效的IL代码

setValue仅支持简单类型(int、float等)

不,不是
FieldBuilder
FieldInfo
继承
SetValue()
,但它对
FieldBuilder
没有意义

有,但它仅适用于
const
字段。并且,引用类型的
const
字段不能具有除
null
以外的值

您需要做的是任何编译器都必须做的事情:创建一个静态构造函数,在那里创建数组,然后将其分配给字段:

var fb = tb.DefineField("A", typeof(int[]), FieldAttributes.Public | FieldAttributes.Static);

var ctor = tb.DefineTypeInitializer();

var il = ctor.GetILGenerator();

// new int[3]
il.Emit(OpCodes.Ldc_I4_3);
il.Emit(OpCodes.Newarr, typeof(int));

// array[0] = 1
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Stelem_I4);

// array[1] = 2
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Stelem_I4);

// arr[2] = 3
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldc_I4_3);
il.Emit(OpCodes.Stelem_I4);

// A = array
il.Emit(OpCodes.Stsfld, fb);

il.Emit(OpCodes.Ret);

如果查看C编译器生成的反编译代码,您可能会看到不同的IL,使用类似
。\uu StaticArrayInitTypeSize=12
和。这是一种优化,我认为如果你是手工编写IL,使用我上面介绍的常规方法会更简单。

我的一般建议是,用C#编写你想要实现的东西,用ildasm进行分解,然后查看输出以获取想法。你定义了A的类型吗
DefineField(“A”,FieldAttributes.Public | FieldAttributes.Static)
似乎缺少类型参数,或者我缺少了什么?@nXu这可能只是复制粘贴错误。你真的不能这样使用
SetValue()
。谢谢。我更喜欢使用这个optim,但我想你建议的版本会一切顺利。一些评论可以让它完全工作。与其使用Dup,不如加载字段
cbilgen.Emit(OpCodes.Ldsfld,fb)存储字段必须位于开头。非常感谢!