Question

dans mon application, je dois créer dynamiquement un type qui contient plusieurs propriétés. Je suis conscient que dans des cas comme cela, on doit générer un CIL pour les deux méthodes getter et setter d'une propriété en utilisant un ILGenerator.

Plus par un tâtonnement que toute autre chose, je me suis enfin arrivé au code suivant qui génère une méthode setter pour moi:

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

Le code fonctionne assez bien, mais il y a une chose que je ne comprends pas. Pourquoi est-il nécessaire d'appeler l'instruction 'Ldarg_0'?

je sais que cela se réfère au premier argument implicite du procédé, la « présente » référence, de sorte que la valeur réelle pour le dispositif de réglage est stocké dans le second argument. Je pensais qu'il devrait être suffisant pour appeler l'instruction Ldarg_1 seulement, ce qui pousserait le second argument de la pile (à la fin, dans le setter, je n'ai pas besoin d'examiner la référence « ce » donc je ne dois pas faire quoi que ce soit avec lui), mais cela se traduit par l'TargetInvocationException jetés lorsque je tente de définir la valeur de la propriété.

Merci!

Était-ce utile?

La solution

Si vous ne poussez pas la « cette » valeur sur la pile, comment Stfld savoir que le champ de l'objet au changement? Vous pouvez essayer d'écrire un setter comme ceci:

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

En gros, Stfld est documenté avoir besoin de deux valeurs sur la pile: une pour la « cible » de la nouvelle valeur, et une pour la valeur elle-même. Il est vrai que le diagramme de transition d'empilement en ECMA 335 est plus claire:

…, obj, value => …,

En d'autres termes: «stfld s'affiche les deux premiers éléments de la pile »

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top