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

StackOverflow https://stackoverflow.com/questions/2555769

Вопрос

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

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

Это было полезно?

Решение

Посмотрите здесь, в частности, раздел 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.Этот метод используется для задания определенного элемента массива, где аргументы указывают индекс для каждого измерения, начиная с первого, устанавливаемого элемента и последний аргумент указывает значение для сохранения в целевом элементе.

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top