Система. Массив служит базовым классом для всех массивов в Общеязыковой среде выполнения (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. Я пишу компилятор для языка, который поддерживает многомерные массивы, таким образом, я хотел бы найти некоторую официальную документацию об этих методах, при каких условиях я могу ожидать, что они будут существовать и чем я могу ожидать, что их подписи будут.
В частности, я хотел бы знать ли его возможное получать a MethodInfo
объект для Get
или Set
для использования с Reflection.Emit
не имея необходимость создавать экземпляр массива с корректным типом и размерностью, над которой можно отразиться, как сделан в связанном примере.
Посмотрите здесь, а именно раздел 14.2 на страницах 63-65
Но главное, что можно понять из IL, это методы getter и setter для работы с массивами в заданных позициях индекса.
- Метод Get, который принимает последовательность из int32 аргументов, по одному для каждого размерность массива, и возвращает значение, тип которого является типом элемента массива. Этот метод используется для доступа к определенному элементу массива где в качестве аргументов указывается индекс в каждом измерении, начиная с первого, элемента, который должен быть возвращается.
- Метод Set, который принимает последовательность аргументов int32, по одному для каждого измерение массива, за которым следует значение, тип которого является типом элемента массива. Тип возврата метода Set является void. Этот метод используется для установки определенного элемента массива, где аргументы задают индекс в каждом измерении, начиная с первого, элемента, который должен быть установлен, и последний аргумент задает значение которое будет сохранено в целевом элементе.
- Метод Address, который принимает последовательность аргументов int32, по одному для каждого измерения массива, и имеет возвращаемый тип, который является управляемым указателем на тип элемента массива. Этот метод используется для возврата управляемого указатель на определенный элемент массива массива, где аргументы задают индекс в каждом измерении, начиная с первого, элемента, чей адрес которого должен быть возвращен.
Edit: Это страницы 63-65, используя нумерацию страниц документа. 73-75 в реальном PDF.
Чтобы ответить на ваш второй вопрос, вам не нужно создавать экземпляр, чтобы получить MethodInfo
для этих методов. Что-то вроде
var mi = typeof(string).MakeArrayType(6).GetMethod("Get");
будет работать для получения метода Get
для типа string [,,,,,]
.
Не уверен, что это поможет ответить на ваш конкретный вопрос, но отличный текст по этой теме (среди прочих) - CLR через C#. В нем очень подробно рассматриваются многие из интересующих вас тем, и много времени уделяется дизассемблеру, рассматривающему внутреннюю работу многих базовых типов .NET, включая массивы. Определенно стоит посмотреть.