Генерация IL для 2D массивов - PullRequest
4 голосов
/ 07 июня 2011

Я хочу сгенерировать IL для построения 2D-массива, используя System.Reflection.Emit пространство имен.

Мой код C # равен

Array 2dArr  = Array.CreateInstance(typeof(int),100,100); 

Используя ildasm, я понял, что после кода ILгенерируется для вышеуказанного кода C #.

IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b:  ldc.i4.s   100
IL_000d:  ldc.i4.s   100
IL_000f:  call       class [mscorlib]System.Array [mscorlib]System.Array::CreateInstance(class [mscorlib]System.Type, 
                                                                                           int32,
                                                                                           int32)

Мне удалось сгенерировать три последних оператора IL, как показано ниже.

MethodInfo createArray = typeof(Array).GetMethod("CreateInstance",
                new Type[] { typeof(Type),typeof(int),typeof(int) });
gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Call, createArray);

Но у меня нет четкого представления о том, каксгенерировать первый оператор IL (т. е. IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle))

Есть ли у вас какие-либо идеи?

Кроме того, может кто-нибудь указать хорошие уроки / документы о том, как использовать пространство имен System.Reflection.Emitдля того, чтобы генерировать коды IL?

1 Ответ

8 голосов
/ 07 июня 2011

Ах, добрый старик typeof; да, это:

 il.Emit(OpCodes.Ldtoken, typeof(int));
 il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);

Повторное руководство ... моя хитрость, если я застреваю, это всегда "скомпилировать что-то подобное и посмотреть на это в рефлекторе".

Если вы хотите, чтобы несколько примеров , dapper-dot-net и protobuf-net оба выполнили приличное количество IL - первое содержит больше, ограниченный и понятный; второй - тотальный, безумный безумный ИЛ.

Подсказки для IL:

  • отслеживание стека в комментариях на КАЖДОМ шаге с правой стороны экрана
  • используйте короткие формы ветвей и т. Д., Но используйте их только тогда, когда вы знаете, что у вас очень локальная ветка
  • напишите себе небольшой набор утилитарных методов даже для простых вещей, таких как загрузка целого числа (что на самом деле довольно сложно, поскольку существует 12 различных способов загрузки int-32, в зависимости от значения)
...