我试图理解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;
}
现在我这样称呼这个方法:
var pr = new Program();
pr.SeeIt = 200;
pr.Prod();
COnsole.WriteLine(pr.SeeIt);
我在下面看到的东西:
我想知道:
答案 0 :(得分:5)
基本上,它的行为完全与没有this
时的行为相同。扩展方法只使API变得方便 - 它们不会改变行为。
参数p
未通过ref
,因此只要您执行p = new Program();
,就会创建一个单独且无关的实例,不可用回到调用代码。因此,来电者不会看到您的更改,100
只会在Prod
中显示。
或更具体地说:
pr.Prod();
与
相同DeclaringType.Prod(pr);
将pr
(引用)的值加载到堆栈上,并通过static-call调用Prod
;
public static void Prod(this Program p)
此时,p
位于堆栈的arg0
位置。
p = new Program();
创建一个新对象并将值分配给 arg0
- 请注意pr
(引用)的值不受此影响,因为arg0
是一个单独的内存位置供参考。
p.SeeIt = 100;
通过解除引用arg0
将成员分配给对象新对象 - 再次, pr
末尾的对象对此一无所知。
答案 1 :(得分:0)
它正在创建Program
的新实例,并且您正在更新该实例的SeeIt
属性。
a)注释#@ 2时,您正在更新Program的原始实例的值,因此设置了属性100
b)创建新实例时,旧实例不受影响且属性值不受影响
答案 2 :(得分:0)
您正在将p的引用替换为另一个实例,这不会影响您传递给扩展方法的引用。我认为你要做的是将参数p作为ref参数,在这种情况下,传递给方法和在方法本身中使用的参数之间的引用将是相同的。
不幸的是,您无法使用引用此参数的扩展方法。
请记住,引用基本上是指向实际类实例的指针。