Pregunta

Estoy utilizando System.Reflection.Emit, y en algún momento quiero crear un delegado de un MethodBuilder:

MethodBuilder fooBuilder = createFooMethodBuilder();
ILGenerator ilGenerator = ...
Type delegateType = typeof(DelegateType);
LocalBuilder delegateVar = ilGenerator.DeclareLocal(delegateType);
//Somehow create emit instructions to create delegate from fooBuilder
//Store delegate in delegateVar using 

Me podría descubrir que para crear delegados de funciones estáticas se usa algo como esto:

ldnull 
ldftn void class Test.MainClass::bar()
newobj instance void class Test.DelegateType::'.ctor'(object, native int)

Pero ahora estoy atascado. Necesito una manera de ldftn la MethodBuilder y entonces necesito una manera de emitir la instrucción para la siguiente línea. Y no tengo ni idea de cómo llegar a un constructor que acepta un int nativo.

¿Alguna sugerencia?

¿Fue útil?

Solución

A native int es un IntPtr en C #.

Se puede obtener el ConstructorInfo para el tipo de delegado utilizando Type.GetConstructor:

var constructorInfo =
    delegateType.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) });

A continuación, puede emitir las instrucciones IL así:

il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ldftn, someMethodInfo);
il.Emit(OpCodes.Newobj, constructorInfo);

Otros consejos

La clase ILGenerator tiene una sobrecarga Emit que toma un MethodInfo, por lo que puede hacer algo como ilGenerator.Emit(Opcodes.ldftn, mi), donde mi es el método al que desea llamar. Puede ser cualquier método que pueda encontrar con la API de reflexión, o incluso otro método que ha creado con un MethodBuilder (que deriva de MethodInfo).

Del mismo modo, para llamar a un constructor que le emita una instrucción newobj proporcionando una ConstructorInfo para la sobrecarga de destino.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top