すべての引数をCILメソッドにスタックにロードする必要があるのはなぜですか?

StackOverflow https://stackoverflow.com/questions/3471608

質問

私のアプリケーションでは、複数のプロパティを含むタイプを動的に作成する必要があります。このような場合、Ilgeneratorを使用して、プロパティのゲッターメソッドとセッターメソッドの両方に対して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」命令を呼び出す必要があるのですか?

メソッドの暗黙の最初の引数である「この」参照を指していることを知っています。したがって、セッターの実際の値は2番目の引数に保存されます。 LDARG_1命令のみを呼び出すだけで十分であるべきだと思いました。それで何でもします)が、これにより、プロパティの価値を設定しようとすると、TargetInvocationExceptionがスローされます。

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

役に立ちましたか?

解決

「この」値をスタックに押し付けなかった場合、どのようにしますか Stfld どのオブジェクトのフィールドを変更するかを知っていますか?このようなセッターを書こうとしている可能性があります。

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

基本的に、 Stfld文書化 スタックに2つの値が必要です。1つは新しい値の「ターゲット」用、もう1つは値自体に必要です。確かに、ECMA 335のスタック遷移図はより明確です。

…, obj, value => …,

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top