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