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

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 ]

5 голосов
/ 31 марта 2010

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

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

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

2 голосов
/ 01 апреля 2010

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

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

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

1 голос
/ 31 марта 2010

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

...