Pregunta

En mi aplicación necesito crear dinámicamente un tipo que contenga múltiples propiedades. Soy consciente de que en casos como este, uno tiene que generar un CIL para los métodos de Getter y Setter de una propiedad mediante el uso de un ILGenerator.

Más por una prueba y error que cualquier otra cosa, finalmente llegué al siguiente código que genera un método de setter para mí:

MethodBuilder setMethod = customTypeBuilder.DefineMethod(propertyName + "_set", MethodAttributes.Public | MethodAttributes.HideBySig, null, new Type[] {propertyType});
ILGenerator setIlGenerator = setMethod.GetILGenerator();
setIlGenerator.Emit(OpCodes.Ldarg_0);
setIlGenerator.Emit(OpCodes.Ldarg_1);
setIlGenerator.Emit(OpCodes.Stfld, backingField);
setIlGenerator.Emit(OpCodes.Ret);

El código funciona lo suficientemente bien, pero hay una cosa que no entiendo al respecto. ¿Por qué es necesario llamar a la instrucción 'lDarg_0'?

Sé que se refiere al primer argumento implícito del método, la referencia "esta", por lo que el valor real para el setter se almacena en el segundo argumento. Pensé que debería ser suficiente llamar solo la instrucción LDARG_1, lo que empujaría el segundo argumento a la pila (al final, en el setter, no necesito examinar la referencia "esta" para que no necesito Haga cualquier cosa con él), pero esto da como resultado que el TargetInVocationException se arroje cuando intento establecer el valor de la propiedad.

¡Gracias!

¿Fue útil?

Solución

Si no empujó el valor "este" a la pila, ¿cómo Stfld ¿Sabes qué campo de objeto cambiar? Podrías estar tratando de escribir un setter como este:

public int Bizarre
{
    set { otherObject.Field = value; }
}

Básicamente, Stfld es documentado para necesitar dos valores en la pila: uno para el "objetivo" del nuevo valor y otro para el valor en sí. Es cierto que el diagrama de transición de la pila en ECMA 335 es más claro:

…, obj, value => …,

En otras palabras: "STFLD aparecerá los dos elementos principales de la pila".

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