すべての引数をCILメソッドにスタックにロードする必要があるのはなぜですか?
-
28-09-2019 - |
質問
私のアプリケーションでは、複数のプロパティを含むタイプを動的に作成する必要があります。このような場合、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つの要素をポップします」。
所属していません StackOverflow