繁体   English   中英

将一个对象分配给同一个类的另一个对象

[英]Assigning one object to another of the same class

请看下面的代码:

class Parent{}

class Child : Parent
{
    public int field 
    {
        get; 
        set;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Child child1 = new Child();
        Child child2 = child1;              //same memory address?

        child1.field = 12;
        child2.field = 14;

        Console.WriteLine(child1.field);    //14, as expected

        child1 = null;
        Console.WriteLine(child2.field);    //expected to crush: 'child1' is null so expected 'child2' to also be null

        Console.ReadLine();
    }
}

我希望这段代码崩溃,但事实并非如此。

为什么?

这不是参考工作的方式。

Child child1 = new Child();

创建对新Child对象的引用

Child child2 = child1;  

创建指向child1执行的同一对象的另一个引用

child1 = null;

child1 引用设置为null (它不再指向任何内容)。 它不会更改它指向的对象,也不会影响child2 child2仍然指向它之前所做的相同对象。

不,您只是将child1变量中包含的引用值设置为空值。
第二个对象实例仍包含原始参考值,仍然有效

以非常简单的方式,当你写

Child child1 = new Child();

child1实例在内存中创建,并返回对它的引用,其值可以表示为值1000 该值(引用)被分配给child1变量

Child child2 = child1;              

您将相同的参考值1000分配给第二个变量

child1 = null;

您将变量child1设置为零(或者null的实现者决定为null),但chidl2仍包含引用值1000。

仍然有正确创建原始对象的内存区域的有效引用阻止垃圾收集器从内存中删除对象,您仍然可以安全地使用第二个变量

与值类型变量不同,引用变量仅仅是指向对象实例的指针 您可以将多个变量指向同一个对象; 将其中一个设置为null不会使对象本身不可用。 这就像你说“ 现在这不再指向任何地方 ”。 因此,它不会影响实例,更不用说仍然指向它的其他变量。

在您的代码中,您所做的是将child1变量设置child1 null ,而child2仍然指向您的实例。 因此,代码完全有效,不会崩溃。 我的理解可能会产生混淆,因为该field财产确实改变两个child1child2 ,但它确实有一定道理,当你意识到他们都指向同样的实例。 在这一点上,真正受到影响的不是child1child2本身; 它是Child实例的field成员,都指的是那个。

当您的对象实例不存在其他指针时,垃圾收集器最终会从内存中清除它。 但是,只要有东西指向它并且指针仍然在范围内,实例就不会去任何地方。

当您将对象分配给同一类的另一个对象时,内存地址或引用是相同的。

但是当你做child1=null; child2仍然引用它在初始化期间引用的同一个对象。

首先,创建一个子对象并将其分配给变量child1

Child child1 = new Child();

所以你可以认为它看起来像这样, child1指向一个Child对象的实例

child1 ---->  { Child object }

然后你这样做:

Child child2 = child1;

这会复制引用,所以现在两个变量都指向同一个对象:

child1 ---->  { Child object }
child2 ------------^

然后你这样做:

child1 = null;

这将从变量child1删除对Child对象实例的引用。 这里重要的一点是Child对象本身不受此影响:

child1        { Child object }
child2 ------------^

因此,由于child2有一个引用的副本 ,它也不会受到影响,仍然指向您在开始时创建的Child实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM