2

私はc#の拡張メソッドの動作を理解しようとしていて、以下のものを見つけました:

以下は、SeeItと呼ばれる1つのフィールドを持つクラスProgramの拡張メソッドです。

public static void Prod(this Program p)
{
   Console.WriteLine("i am in ext- pro" );
   p = new Program();   // look out for this line (call this line as #@2)
   p.SeeIt = 100;
}

このようにこのメソッドを呼び出すと:

var pr = new Program();
pr.SeeIt = 200;

pr.Prod();

COnsole.WriteLine(pr.SeeIt);

私は以下のものを見る:

  1. 拡張メソッドの#@ 2行にコメントすると、結果は拡張メソッド、つまり100からのものになります。
  2. 行#@ 2行を保持すると、結果は200になります。

私は知りたいです :

  • Extensionメソッドのp=new Program()と言うと、そこで何が起こっているのでしょうか。
4

3 に答える 3

5

基本的に、。がない場合とまったくthis同じように動作します。拡張メソッドはAPIを便利にするだけで、動作を変更しません。

パラメータpは渡されないrefため、渡されるとすぐに、呼び出し元のコードで使用できないp = new Program();別の無関係なインスタンスを作成します。その結果、発信者には変更が表示されず、はにのみ表示されます。100Prod

またはより具体的に:

pr.Prod();

と同じです

DeclaringType.Prod(pr);

pr(参照)の値をスタックにロードし、Prodstatic-callを介して呼び出します。

public static void Prod(this Program p)

この時点で、pはスタックの位置にありarg0ます。

p = new Program();

新しいオブジェクトを作成し、値を 割り当てます-参照用の個別のメモリ位置と同様に、(参照)の値はこれによる影響を受けないarg0ことに注意してください。prarg0

p.SeeIt = 100;

逆参照することにより、オブジェクトにメンバーを新しいオブジェクトに割り当てます。この場合も、最後のarg0オブジェクトはこれについて何も知りません。 pr

于 2012-04-13T05:39:12.443 に答える
0

の新しいインスタンスを作成していて、そのインスタンスのプロパティをProgram更新しています。SeeIt

a)#@ 2がコメント化されると、Programの元のインスタンスの値が更新されるため、プロパティ100が設定されます。

b)新しいインスタンスを作成する場合、古いインスタンスは影響を受けず、プロパティ値も影響を受けません

于 2012-04-13T05:41:02.497 に答える
0

pの参照を別のインスタンスに置き換えていますが、これは拡張メソッドに渡した参照には影響しません。あなたがやろうとしていたのは、パラメーターpa refパラメーターを作成することだったと思います。その場合、メソッドに渡されたものとメソッド自体で使用されているものの間の参照は同じになります。

残念ながら、このパラメータを参照する拡張メソッドを実行することはできません。

参照は基本的に実際のクラスインスタンスへのポインタであることを忘れないでください。

于 2012-04-13T05:45:53.243 に答える