System.Array充当公共语言运行时(CLR)中所有数组的基类。根据{{3}}:
对于每个具体的数组类型,[]运行时添加了三种特殊方法:
Get
/Set
/Address
。
确实如果我反汇编这个C#代码,
int[,] x = new int[1024,1024];
x[0,0] = 1;
x[1,1] = 2;
x[2,2] = 3;
Console.WriteLine(x[0,0]);
Console.WriteLine(x[1,1]);
Console.WriteLine(x[2,2]);
进入CIL我明白了,
IL_0000: ldc.i4 0x400
IL_0005: ldc.i4 0x400
IL_000a: newobj instance void int32[0...,0...]::.ctor(int32,
int32)
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: ldc.i4.0
IL_0012: ldc.i4.0
IL_0013: ldc.i4.1
IL_0014: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_0019: ldloc.0
IL_001a: ldc.i4.1
IL_001b: ldc.i4.1
IL_001c: ldc.i4.2
IL_001d: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_0022: ldloc.0
IL_0023: ldc.i4.2
IL_0024: ldc.i4.2
IL_0025: ldc.i4.3
IL_0026: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_002b: ldloc.0
IL_002c: ldc.i4.0
IL_002d: ldc.i4.0
IL_002e: call instance int32 int32[0...,0...]::Get(int32,
int32)
IL_0033: call void [mscorlib]System.Console::WriteLine(int32)
IL_0038: ldloc.0
IL_0039: ldc.i4.1
IL_003a: ldc.i4.1
IL_003b: call instance int32 int32[0...,0...]::Get(int32,
int32)
IL_0040: call void [mscorlib]System.Console::WriteLine(int32)
IL_0045: ldloc.0
IL_0046: ldc.i4.2
IL_0047: ldc.i4.2
IL_0048: call instance int32 int32[0...,0...]::Get(int32,
int32)
IL_004d: call void [mscorlib]System.Console::WriteLine(int32)
可以清楚地看到对上述Get
和Set
方法的调用。看起来这些方法的优点与数组的维度有关,这可能是它们由运行时创建并且未预先声明的原因。我无法在MSDN上找到有关这些方法的任何信息,它们的简单名称使它们对谷歌搜索具有抵抗力。我正在为支持多维数组的语言编写一个编译器,所以我想找到一些关于这些方法的官方文档,在什么条件下我可以期望它们存在以及我可以期待它们的签名。
特别是,我想知道是否有可能获得MethodInfo
或Get
的{{1}}对象与Set
一起使用而无需创建<具有正确类型和维度的数组的em> instance ,如链接示例中所做的那样。
答案 0 :(得分:5)
请看这里,特别是第63-65页的第14.2节
但是从IL可以看出,它们是在给定索引位置处理数组的getter和setter方法。
•一个获取序列的Get方法 int32参数,每个参数一个 数组的维度,并返回一个 类型为元素类型的值 数组。这种方法用于 访问数组的特定元素 其中参数指定索引 从每个维度开始 第一个,要素 返回。
•采用序列的Set方法 int32参数,每个参数一个 数组的维度,后跟一个 类型为元素类型的值 数组。 Set的返回类型 是无效的。此方法用于设置a 数组的特定元素在哪里 参数指定索引 每个维度,从...开始 首先,要设置的元素和 最后一个参数指定值 存储到目标元素中。
•采用a的Address方法 int32参数的序列,一个用于 数组的每个维度,并有一个 返回类型是托管指针 到数组的元素类型。这个 方法用于返回托管 指向特定元素的指针 参数指定的数组 从每个维度开始索引 与第一个元素的元素 地址将被退回。
编辑:使用文档的页码编号,这是第63-65页。实际PDF中的73-75。
答案 1 :(得分:2)
要回答第二个问题,您无需为这些方法创建一个实例来获取MethodInfo
。像
var mi = typeof(string).MakeArrayType(6).GetMethod("Get");
将获得Get
类型的string[,,,,,]
方法。
答案 2 :(得分:1)
我不确定它是否会解决您的具体问题,但有关该主题(包括其他内容)的优秀文字是CLR via C#。对于您感兴趣的许多主题,它非常深入,并且花费大量时间与反汇编程序一起查看许多基本.NET类型(包括数组)的内部工作方式。绝对值得一试。