2009-09-06 2 views
2

Я бы хотел создать динамически некоторый метод, который будет принимать единственный параметр - экземпляр класса A, а затем выполнит метод B в переданном экземпляре A. B имеет параметр типа int. Так вот схема:Reflection.Emit для динамического создания метода

dynamicMethod(A a){ 
a.B(12); 
} 

Вот что я пробовал:

DynamicMethod method = new DynamicMethod(string.Empty, typeof(void), new[] { typeof(A) }, typeof(Program)); 
MethodInfo methodB = typeof(A).GetMethod("B", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null); 
ILGenerator gen = method.GetILGenerator(); 

gen.Emit(OpCodes.Nop); 
gen.Emit(OpCodes.Ldarg_0); 
gen.Emit(OpCodes.Ldarg_S, 100); 
gen.Emit(OpCodes.Call, methodB); 

Но компилятор говорит мне, что CLR не найден метод. Не могли бы вы мне помочь?

+1

Вы можете использовать 'System.Linq.Expressions' для компиляции дерева выражений. Это легче. –

ответ

1

MSDN о the types parameter of the Type.GetMethod function:

Массив объектов типа, представляющая число, порядок и тип параметров для метода, чтобы получить.

Вы передаете пустой массив, который указывает «метод, который не принимает параметров». Но, как вы сказали, «B имеет параметр [a] типа int».

Это будет работать:

MethodInfo methodB = typeof(A).GetMethod(
      "B", 
      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
      null, 
      new Type[] { typeof(int) } 
      , null); 

Если я правильно понимаю Ldarg_S загрузит сотый аргумент вашего метода, вывести так Ldarg_0:

gen.Emit(OpCodes.Ldarg_S, 100); 

Для загрузки использовать постоянное значение Ldc_I4

gen.Emit(OpCodes.Ldc_I4, 100); 
+0

Да, правильно, но как передать этот параметр через метод Emit? Какой OpCode я должен использовать? –