Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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# - Fatal编程技术网

C# 如何理解链接时对象是否被复制或引用

C# 如何理解链接时对象是否被复制或引用,c#,C#,很抱歉,我是编程新手,所以我的描述可能不正确。我设计了一个使用linkedNode结构的类: class test { public int data, public test next; public test(int data){this.data = data;} } 主要内容: public static void main(){ test t1 = new test(1), t2 = new test(2); //Line 1

很抱歉,我是编程新手,所以我的描述可能不正确。我设计了一个使用linkedNode结构的类:

class test {
    public int data,
    public test next;   
    public test(int data){this.data = data;}     
}
主要内容:

public static void main(){
    test t1 = new test(1), t2 = new test(2); //Line 1
    t1.next = t2; //Line 2
    t2.next = t1; //Line 3
    t2 = null; //Line 4
    Console.Write(t1.next.next.next.......data) // Line 5
}

所以我的next()似乎可以无限期地调用,但我很好奇
t2
如何连接到
t1.next
?如果将
t2
复制到
t1.next
,则第3行将无法将其作为循环;如果
t2
仅通过地址链接,则第4行将中断循环。所以我很困惑我的代码背后发生了什么?

事实上,你的两个结论都不正确。不会复制对象,但第4行不会“打断循环”。让我们把它分解一下:

test t1 = new test(1), t2 = new test(2); //Line 1
这将创建两个“测试”对象,并将其引用存储在局部变量中。因为它们都有一个值来标识它们(在本例中不会改变),所以我们将它们称为“thing1”和“thing2”

好的。“thing1”的
next
属性现在引用“thing2”(从技术上讲,引用“thing2”的
t2的值被复制到
t1。next

还不错。“thing2”的
next
属性现在引用“thing1”(从技术上讲,引用“thing1”的
t1的值被复制到
t2。next

好的。变量
t2
现在不指向任何内容。这里的主要误解是,对“第二件事”没有任何改变。只有引用“Thing2”的变量发生了更改。“第二件事”本身不受影响。它仍然有一个引用“Thing1”的
next
属性。就这点而言,“事情1”也不受影响。它有一个引用“thing2”的
next
属性

t1
引用“thing1”,其
next
属性引用“thing2”,其
next
属性引用“thing1”,其
next
属性引用“thing2”等。因此,根据调用
。next
的次数,结果将是
1
2

我很好奇t2是如何连接到t1的。下一步呢


直到第4行,它们都引用相同的对象。然后,第4行更改了
t2
引用的内容(无),但没有更改
t1的值。接下来

实际上,您的两个结论都不正确。不会复制对象,但第4行不会“打断循环”。让我们把它分解一下:

test t1 = new test(1), t2 = new test(2); //Line 1
这将创建两个“测试”对象,并将其引用存储在局部变量中。因为它们都有一个值来标识它们(在本例中不会改变),所以我们将它们称为“thing1”和“thing2”

好的。“thing1”的
next
属性现在引用“thing2”(从技术上讲,引用“thing2”的
t2的值被复制到
t1。next

还不错。“thing2”的
next
属性现在引用“thing1”(从技术上讲,引用“thing1”的
t1的值被复制到
t2。next

好的。变量
t2
现在不指向任何内容。这里的主要误解是,对“第二件事”没有任何改变。只有引用“Thing2”的变量发生了更改。“第二件事”本身不受影响。它仍然有一个引用“Thing1”的
next
属性。就这点而言,“事情1”也不受影响。它有一个引用“thing2”的
next
属性

t1
引用“thing1”,其
next
属性引用“thing2”,其
next
属性引用“thing1”,其
next
属性引用“thing2”等。因此,根据调用
。next
的次数,结果将是
1
2

我很好奇t2是如何连接到t1的。下一步呢


直到第4行,它们都引用相同的对象。第4行然后更改
t2
引用的内容(无),但不更改
t1的值。下一步
D Stanley的答案很好,但我想给出一个更真实的类比,更细粒度的步骤可能有助于您遵循。我将检查代码的每一部分,并将其转换为这个类比。我在构造函数中更改了参数的名称,使事情更清楚一点

class test {
您创建了一个名为“测试”的生产说明,说明了什么应该包装在纸板箱中,以及如何将东西放入其中

    public int data,
将有一张打印有“数据”标签的纸条放在盒子里,这张纸条将有一个点可以写在-2147483648和2147483647之间的数字上。纸张的默认值为“已铅笔描入”值0

    public test next;
另一张标有“下一张”的纸将放在盒子里,这是一张特殊的纸,只允许你在一个架子上写下一个位置,架子是用来在仓库里放“测试”盒子的。默认情况下,此位置将保留为空

    public test(int newData){this.data = newData;}     
}
这是包装说明,说明上写着“我会给你一张标有“新数据”的纸条,上面有一个数字。你要在标有“数据”的纸条上写上我给你的“新数据”纸条上的数字。当你写完后,你扔掉我最初给你的标有“新数据”的纸条。”

擦除标记为“t2”的纸上的数字

你今天回家

    test t1 = -->new test(1)<--
在盒子上写下原始值后,您从未修改过盒子内的纸张,您只删除了办公室中的纸张编号,因此删除该编号不会影响读取两个盒子中的“下一张”纸张


这里有一点额外的信息,关于如何使用相同的类比来收集对象的垃圾

    t2 = null; //Line 4
    --><---
    Console.Write(t1.next.next.next.......data) // Line 5
}
t2=null//第4行
-->{
测试t1=新测试(1),t2=新测试(2);//第1行
t1.next=t2;//第2行
t2.next=t1;//第3行
t2=null;//第4行
控制台
    public test(int newData){this.data = newData;}     
}
public static void main() -->{<--
    test t1 = -->new test(1)<--
    --> test t1 =<-- new test(1), t2 = new test(2); //Line 1
    test t1 = new test(1), -->t2 = new test(2);<-- //Line 1
    -->t1.<--next = t2; //Line 2
    t1-->.next = t2<--; //Line 2
    -->t2.<--next = t1; //Line 3
    t2-->.next = t1<--; //Line 3
    t2 = null; //Line 4
    Console.Write(-->t1.<--next.next.next.......data) // Line 5
    Console.Write(t1.-->next.<--next.next.......data) // Line 5
    Console.Write(t1.next-->.next.<--next.......data) // Line 5
    Console.Write(t1.next.next-->.next.<--......data) // Line 5
    Console.Write(t1.next.next.next-->.......<--data) // Line 5
    Console.Write(t1.next.next.next......-->.data<--) // Line 5
    -->Console.Write(t1.next.next.next.......data)<-- // Line 5
}
    t2 = null; //Line 4
    --><---
    Console.Write(t1.next.next.next.......data) // Line 5
}
    t2 = null; //Line 4
    Console.Write(t1.next.next.next......-->.data<--) // Line 5
    --><---
}
 public static void main() -->{
    test t1 = new test(1), t2 = new test(2); //Line 1
    t1.next = t2; //Line 2
    t2.next = t1; //Line 3
    t2 = null; //Line 4
    Console.Write(t1.next.next.next.......data) // Line 5
}<--