在方法中创建新对象时扩展方法的混乱行为

Rup*_*pal 2 c# extension-methods

我试图理解c#的扩展方法的行为,并在下面找到了东西:

下面是类Program的扩展方法,它有一个名为SeeIt的字段.

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;
}
Run Code Online (Sandbox Code Playgroud)

现在当我这样调用这个方法时:

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

pr.Prod();

COnsole.WriteLine(pr.SeeIt);
Run Code Online (Sandbox Code Playgroud)

我在下面看到的东西:

  1. 当我在扩展方法中评论#@ 2行时,结果来自扩展方法,即100.
  2. 当我保持#2行的行时,结果为200.

我想知道 :

  • 究竟发生了什么,我在扩展方法中说p = new Program()?

Mar*_*ell 5

基本上,它的行为与没有它的行为完全相同this.扩展方法只使API变得方便 - 它们不会改变行为.

该参数p未被传递ref,因此只要p = new Program();您创建了一个单独且无关的实例,该实例将无法返回到调用代码.因此,呼叫者将看不到您的更改,并且100只会显示您的更改Prod.

或者更具体地说:

pr.Prod();
Run Code Online (Sandbox Code Playgroud)

是完全相同的

DeclaringType.Prod(pr);
Run Code Online (Sandbox Code Playgroud)

它将pr(引用)的值加载到堆栈上并Prod通过静态调用进行调用;

public static void Prod(this Program p)
Run Code Online (Sandbox Code Playgroud)

在这一点上,p是在堆栈的位置arg0.

p = new Program();
Run Code Online (Sandbox Code Playgroud)

创建一个新对象,并将值超过 arg0 -注意的那个值pr(基准)不受此影响,因为arg0是针对参考一个单独的存储器位置.

p.SeeIt = 100;
Run Code Online (Sandbox Code Playgroud)

提领分配成员对象新对象arg0再次,目标- 在年底 pr一无所知这一点.