我想知道何时以及为什么引用会在C#中被破坏?
以下代码示例突出显示了这一点:
StringBuilder a = null, b = null;
a = new StringBuilder("a");
b = a;
b.Append("b");
b = null;
Console.WriteLine(a != null? a.ToString() : "null");
Console.WriteLine(b != null ? b.ToString() : "null");
//Output:
ab
null
为什么,对于此示例,b
对a
的引用不会导致a
成为null
?
答案 0 :(得分:12)
您需要区分变量,引用和对象。
这一行:
b = a;
将b
的值设置为a
的值。该值是参考。它是对对象的引用。此时,通过 a
或b
对该对象进行更改只会对同一对象进行更改 - 这些更改将通过a
显示或b
,因为两者仍然引用同一个对象。
它们就像两张纸,上面写着相同的住宅地址 - 这两个变量对彼此一无所知,它们只是发生具有相同的值,因为上一行。
因此,当我们在此行上更改b
的值时:
b = null;
只是会更改b
的值。它将b
的值设置为空引用。这不会更改a
或 StringBuilder
对象的值,b
的旧值会引用该对象。
我有article which goes into more details on this,您可能会觉得有用。
答案 1 :(得分:11)
变量b
没有对变量a
的引用,它引用了StringBuilder
引用的a
对象。这就是b=a
所做的,它为b
分配了对a
引用的对象的引用。只要是这种情况,当通过b
使用对象时,通过a
对对象的任何更改都是可见的。
当b
被分配null
时,它不再具有对任何对象的引用,但a
仍然保留其引用。
这是一张描绘这张照片的照片:
答案 2 :(得分:7)
您需要单独考虑引用和对象。有一个对象StringBuilder
。引用本质上是对象的内存位置(给出或采取一些名义上的抽象),其值为某个大整数。你有两个引用变量。
StringBuilder a = null, b = null; // both variables empty
a = new StringBuilder("a"); // a ref to the obj, b empty
b = a; // copy value (ref) of a to b: a and b both ref to obj
b.Append("b"); // no change to either VARIABLE; the OBJECT has changed state
b = null; // clear the variable b; a still points to the obj
另请注意,即使我们添加
a = null; // both variables empty
我们还有2个空变量和一个对象;对象不会神奇地消失 - 这就是垃圾收集(GC)的用途。
答案 3 :(得分:6)
b没有对a的引用。没有“a”可以参考。内存中有一个对象(stringbuilder)和两个引用它的不同变量。第b = a
行在a中创建引用的副本,并将其分配给b。
答案 4 :(得分:2)
当您设置b = a;
时,您说“b
指向a
也指向内存的对象。”所以当你这样做时:
b.Append("b");
这样做完全相同:
a.Append("b");
但它的真实情况(a
和b
)是:
[Object memory reference of a and b].Append("b");