在哪里可以找到有关 .NET 中多维 System.Array 实例的 Get、Set 和 Address 方法的信息?
System.Array 作为所有数组的基类公共语言运行时 (CLR)。根据这篇文章< /a>:
对于每种具体数组类型,运行时添加了三个特殊方法:
Get
/Set
/Address
。
事实上,如果我
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]);
将这段 C# 代码反汇编成 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 上找不到有关这些方法的任何信息,而且它们简单的名称使它们无法通过 Google 搜索。我正在为支持多维数组的语言编写一个编译器,因此我想找到一些有关这些方法的官方文档,在什么条件下我可以期望它们存在以及我可以期望它们的签名是什么。
特别是,我想知道是否可以为 Get
或 Set
获取 MethodInfo
对象以与 Reflection 一起使用。发射
,而无需创建具有正确类型和维度的数组实例来反映,如链接示例中所做的那样。
System.Array serves as the base class for all arrays in the Common Language Runtime (CLR). According to this article:
For each concrete array type, [the] runtime adds three special methods:
Get
/Set
/Address
.
and indeed if I disassemble this C# code,
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]);
into CIL I get,
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)
where the calls to the aforementioned Get
and Set
methods can be clearly seen. It seems the arity of these methods is related to the dimensionality of the array, which is presumably why they are created by the runtime and are not pre-declared. I couldn't locate any information about these methods on MSDN and their simple names makes them resistant to Googling. I'm writing a compiler for a language which supports multidimensional arrays, so I'd like to find some official documentation about these methods, under what conditions I can expect them to exist and what I can expect their signatures to be.
In particular, I'd like to know whether its possible to get a MethodInfo
object for Get
or Set
for use with Reflection.Emit
without having to create an instance of the array with correct type and dimensionality on which to reflect, as is done in the linked example.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看这里,特别是第 63-65 页的 14.2 节
http://download.microsoft.com/download/7/3/3/733AD403-90B2-4064-A81E-01035A7FE13C/MS%20Partition%20II.pdf
但要点,您可以从 IL 看出,它们是处理给定索引位置处的数组的 getter 和 setter 方法。
编辑:这是使用文档页码编号的第 63-65 页。实际 PDF 中的 73-75。
Look here, specifically section 14.2 on pages 63-65
http://download.microsoft.com/download/7/3/3/733AD403-90B2-4064-A81E-01035A7FE13C/MS%20Partition%20II.pdf
But the takeaway, and you can tell from the IL, is that they're the getter and setter methods for dealing with arrays at the given index positions.
Edit: That's pages 63-65 using the document's page numbering. 73-75 in the actual PDF.
要回答第二个问题,您不需要创建实例来获取这些方法的
MethodInfo
。类似的方法可以获取
string[,,,,,]
类型的Get
方法。To answer your second question, you don't need to create an instance to get a
MethodInfo
for these methods. Something likewill work to get the
Get
method for thestring[,,,,,]
type.我不确定它是否能解决您非常具体的问题,但关于该主题(除其他外)的精彩文本是 通过 C# 进行 CLR。它对您感兴趣的许多主题进行了非常深入的研究,并花费大量时间使用反汇编程序来查看许多基本 .NET 类型(包括数组)的内部工作原理。绝对值得一看。
I'm not sure if it will address your very specific question but a great text on the subject (among others) is CLR via C#. It gets very in-depth for many of the topics you're interested in and spends a lot of time with the disassembler looking at the inner workings of many base .NET types including arrays. Definitely worth checking out.