Где я могу найти информацию о методах Get, Set и Address для многомерных экземпляров System.Array в.NET?

System.Array служит базовым классом для всех массивов в Common Language Runtime (CLR). Согласно этой статье:

Для каждого конкретного типа массива среда выполнения [] добавляет три специальных метода: 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, и их простые имена делают их устойчивыми к поиску в Google. Я пишу компилятор для языка, который поддерживает многомерные массивы, поэтому я хотел бы найти некоторую официальную документацию об этих методах, при каких условиях я могу ожидать их существования и каковы могут быть их сигнатуры.

В частности, я хотел бы знать, возможно ли получить MethodInfo объект для Get или же Set для использования с Reflection.Emit без необходимости создавать экземпляр массива с правильным типом и размерностью для отражения, как это делается в связанном примере.

3 ответа

Решение

Смотрите здесь, в частности, раздел 14.2 на страницах 63-65.

http://download.microsoft.com/download/7/3/3/733AD403-90B2-4064-A81E-01035A7FE13C/MS%20Partition%20II.pdf

Но выгода, и вы можете сказать из IL, состоит в том, что они являются методами получения и установки для работы с массивами в данных позициях индекса.

• Метод Get, который принимает последовательность аргументов int32, по одному для каждого измерения массива, и возвращает значение, тип которого является типом элемента массива. Этот метод используется для доступа к конкретному элементу массива, где аргументы указывают индекс для каждого измерения, начиная с первого, возвращаемого элемента.

• Метод Set, который принимает последовательность аргументов int32, по одному для каждого измерения массива, за которым следует значение, тип которого является типом элемента массива. Тип возвращаемого значения Set - void. Этот метод используется для установки определенного элемента массива, в котором аргументы указывают индекс для каждого измерения, начиная с первого, устанавливаемого элемента, а последний аргумент указывает значение, которое будет сохранено в целевом элементе.

• Метод Address, который принимает последовательность аргументов int32, по одному для каждого измерения массива, и имеет возвращаемый тип, который является управляемым указателем на тип элемента массива. Этот метод используется для возврата управляемого указателя на определенный элемент массива, где аргументы указывают индекс для каждого измерения, начиная с первого, элемента, адрес которого должен быть возвращен.

Изменить: Это страницы 63-65 с использованием нумерации страниц документа. 73-75 в актуальном PDF.

Чтобы ответить на ваш второй вопрос, вам не нужно создавать экземпляр, чтобы получить MethodInfo для этих методов. Что-то вроде

var mi = typeof(string).MakeArrayType(6).GetMethod("Get");

будет работать, чтобы получить Get метод для string[,,,,,] тип.

Я не уверен, что это ответит на ваш очень конкретный вопрос, но отличный текст по этому вопросу (среди прочих) - это CLR через C#. Он очень углублен во многие темы, которые вас интересуют, и проводит много времени с дизассемблером, рассматривая внутреннюю работу многих базовых типов.NET, включая массивы. Определенно стоит проверить.

Другие вопросы по тегам