Где я могу найти информацию о методах Get, Set и Address для многомерной системы.Экземпляры массива в .NET?
-
23-09-2019 - |
Вопрос
Система.Массив служит базовым классом для всех массивов в 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
Но вывод, и вы можете судить по 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, включая массивы.Определенно стоит проверить.