Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将扩展方法的行为与方法中的新对象创建混淆_C#_Extension Methods - Fatal编程技术网

C# 将扩展方法的行为与方法中的新对象创建混淆

C# 将扩展方法的行为与方法中的新对象创建混淆,c#,extension-methods,C#,Extension Methods,我试图理解c#的扩展方法的行为,发现了以下东西: 下面是类程序的扩展方法,它有一个名为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

我试图理解c#的扩展方法的行为,发现了以下东西:

下面是类程序的扩展方法,它有一个名为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);
我看到以下事情:

  • 当我在扩展方法中注释#@2行时,结果来自扩展方法,即100
  • 当我保持2行时,结果是200
  • 我想知道:

    • 扩展方法中的p=new Program()到底是怎么回事
    基本上,它的行为与不使用
    时完全相同。扩展方法只会使API更方便—它们不会改变行为

    参数
    p
    未传递
    ref
    ,因此只要您传递
    p=new Program()您已经创建了一个独立的、不相关的实例,该实例将可供调用代码使用。因此,调用者将看不到您的更改,
    100
    将仅在
    Prod
    中可见

    或者更具体地说:

    pr.Prod();
    
    与相同

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

    public static void Prod(this Program p)
    
    此时,
    p
    位于堆栈上的
    arg0
    位置

    p = new Program();
    
    创建新对象并在
    arg0
    上赋值-注意,
    pr
    (引用)的值不受此影响,因为
    arg0是引用的单独内存位置

    p.SeeIt = 100;
    

    通过取消引用
    arg0
    将成员分配给对象新对象-同样,
    pr
    末尾的对象对此一无所知。

    它正在创建
    程序的新实例,您正在更新该实例的
    SeeIt
    属性

    a) 当#@2被注释时,您正在更新程序的原始实例的值,因此属性100被设置


    b) 创建新实例时,旧实例不受影响,属性值不受影响

    您将p的引用替换为另一个实例,这不会影响传递给扩展方法的引用。我认为您试图做的是将参数p设置为ref参数,在这种情况下,传递给方法的内容与在方法本身中使用的内容之间的引用是相同的

    不幸的是,您不能使用引用此参数的扩展方法


    请记住,引用基本上是指向实际classinstance的指针。

    在发布此问题之前,您是否尝试过调试器流需要调试的代码不多。那么我假设您不知道消息传递