Domanda

nella mia applicazione ho bisogno di creare dinamicamente un tipo che contiene più proprietà. Sono consapevole che in casi come questo, si deve generare un CIL sia per i metodi getter e setter di una proprietà utilizzando un ILGenerator.

Più da un tentativi ed errori di ogni altra cosa, mi sono finalmente arrivato al seguente codice che genera un metodo setter per me:

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);

Il codice funziona abbastanza bene, ma c'è una cosa che non capisco su di esso. Perché è necessario chiamare l'istruzione 'Ldarg_0'?

So che si riferisce al primo argomento implicito del metodo, il "questo" di riferimento, in modo che il valore effettivo del setter è memorizzato nel secondo argomento. Ho pensato che dovrebbe essere sufficiente solo chiamare l'istruzione Ldarg_1, che spingerebbe il secondo argomento alla pila (alla fine, nel setter, ho bisogno di esaminare l' "questo" riferimento quindi non c'è bisogno di fare qualsiasi cosa con esso), ma il risultato è la TargetInvocationException gettati quando tento di impostare il valore della proprietà.

Grazie!

È stato utile?

Soluzione

Se non si preme il "questo" valore nello stack, come sarebbe Stfld sapere quale oggetto di campo per il cambiamento? Si potrebbe tentare di scrivere un setter in questo modo:

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

In sostanza, Stfld è documentato ad avere bisogno di due valori sullo stack: uno per il "target" del nuovo valore, e uno per il valore stesso. Certo diagramma di transizione stack ECMA 335 è chiara:

…, obj, value => …,

In altre parole: "stfld apparirà nella parte superiore due elementi dalla pila"

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top