2

私のアプリケーションでは、複数のプロパティを含む型を動的に作成する必要があります。このような場合、ILGeneratorを使用して、プロパティのgetterメソッドとsetterメソッドの両方に対してCILを生成する必要があることを認識しています。

何よりも試行錯誤の末、ついにセッターメソッドを生成する次のコードにたどり着きました。

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

コードは十分に機能しますが、私が理解していないことが1つあります。'Ldarg_0'命令を呼び出す必要があるのはなぜですか?

メソッドの暗黙の最初の引数である「this」参照を参照していることを知っているので、セッターの実際の値は2番目の引数に格納されます。Ldarg_1命令のみを呼び出すだけで十分だと思いました。これにより、2番目の引数がスタックにプッシュされます(最終的に、セッターでは、「this」参照を調べる必要がないため、次のことを行う必要はありません。それで何でもします)、しかしこれは私がプロパティの値を設定しようとするとTargetInvocationExceptionがスローされる結果になります。

ありがとうございました!

4

1 に答える 1

4

「this」値をスタックにプッシュしなかった場合、どのStfldオブジェクトのフィールドを変更するかをどのように知ることができますか?次のようなセッターを作成しようとしている可能性があります。

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

基本的に、スタック上に2つの値が必要であることStfld文書化されています。1つは新しい値の「ターゲット」用で、もう1つは値自体用です。確かに、ECMA335のスタック遷移図はより明確です。

…, obj, value => …,

言い換えると、「stfldはスタックから上位2つの要素をポップします」。

于 2010-08-12T20:12:56.737 に答える