C# 如何理解链接时对象是否被复制或引用
很抱歉,我是编程新手,所以我的描述可能不正确。我设计了一个使用linkedNode结构的类: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
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
}<--