C#中的引用类型

78 .net c# pointers

考虑以下代码:

public class Program
{
    private static void Main(string[] args)
    {
        var person1 = new Person { Name = "Test" };
        Console.WriteLine(person1.Name);

        Person person2 = person1;
        person2.Name = "Shahrooz";
        Console.WriteLine(person1.Name); //Output: Shahrooz
        person2 = null;
        Console.WriteLine(person1.Name); //Output: Shahrooz
    }
}

public class Person
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

很显然,当分配person1person2Name物业person2发生变化,Nameperson1也将改变.person1person2有相同的参考.

为什么何时person2 = null,person1变量也不会为空?

And*_*rei 182

这两个personperson2引用,同一个对象.但这些是不同的参考.所以当你跑步的时候

person2 = null;
Run Code Online (Sandbox Code Playgroud)

您只更改引用person2,保留引用person和相应的对象不变.

我想解释这个的最好方法是简化说明.这里的情况是怎么看起来像之前 person2 = null:

在空分配之前

这是空分配的图片:

在此输入图像描述

正如你所看到的,在第二张图片person2中没有引用任何东西(或null严格来说,因为没有参考和引用null是不同的条件,请参阅Rune FS的评论),同时person仍引用现有对象.

  • 换句话说,person和person2指向某个东西,然后person2通过设置为null指向任何东西. (22认同)
  • @ShahroozJefriㇱ基本上,`person1`和`person2`是2张包含地址的不同名片.如果你做`person1 = person2`那么`person1`现在是`person2`的副本.它们仍然是*不同的*名片,但它们都包含指向*same*对象的*same*地址.对象本身不会改变. (2认同)
  • 当使用引用,创建变量并将其分配给另一个指针时,会创建一个称为Alias的东西,我们可以说,3个变量指向同一个内存位置.当你使其中一个变量无效时,有一个变量指向那个内存位置,当所有变量都指向NULL时,GC清理该位置以分配新变量,至少在Java中,GC的工作方式为D: (2认同)

Hab*_*bib 55

考虑person1person2 指出存储中的某些位置.在第一步中,仅从person1存储器中保存对象的地址,然后从存储器person2中保存对象的存储器位置的地址.稍后当您分配nullperson2,person1保持不受影响.这就是你看到结果的原因.

您可以阅读:Joseph Albahari的价值与参考类型

但是,对于引用类型,在内存中创建一个对象,然后通过单独的引用处理 - 而不是像指针一样.

我将尝试使用下图描绘相同的概念.

在此输入图像描述

创建了person类型的新对象,person1引用(指针)指向存储中的内存位置.

在此输入图像描述

创建了一个新的引用(指针)person2,它指向存储中的相同内容.

在此输入图像描述

将对象属性Name更改为新值,person2因为两个引用都指向同一对象Console.WriteLine(person1.Name);输出Shahrooz.

在此输入图像描述

在分配nullperson2引用之后,它将指向什么,但person1仍然保持对该对象的引用.

(最后,对于内存管理,你应该看到Stack是一个实现细节,第一部分Stack是一个实现细节, Eric Lippert的第二部分)

  • @jmoreno,就这个答案而言,正确的是`person`类型的对象将存储在堆上,其引用`person1`和`person2`将在堆栈上.但我同意更多的实施细节.但是在答案[*(如albahari的文章)*](http://www.albahari.com/valuevsreftypes.aspx)中有堆叠和堆积会使IMO更加清晰. (4认同)
  • 对"堆"的任何引用都是不相关的实现细节.我甚至不确定这是真的,它当然不需要. (3认同)

No *_*ame 14

您已更改person2为引用null,但未person1引用该引用.

我的意思是,如果我们在分配之前person2person1之前看,那么它们都引用相同的对象.然后你分配person2 = null,所以人2现在引用不同的类型.它没有删除person2引用的对象.

我已经创建了这个gif来说明它:

在此输入图像描述


Sim*_*ead 13

因为您已将引用设置为null.

设置引用时null,引用本身是null..而不是它引用的对象.

将它们视为保持偏移量为0 person的变量.值为120. person2具有值120.偏移量120处的数据是Person对象.当你这样做:

person2 = null;
Run Code Online (Sandbox Code Playgroud)

你有效地说,person2 = 0;.但是,person仍然具有值120.