打破C#引用
我想知道何时以及为什么引用会在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
?
您需要区分变量 , 引用和对象 。
这一行:
b = a;
将b
的值设置为b
的值。 该值是参考。 它是对象的引用。 此时, 通过 a
或b
对该对象进行更改只会对同一对象进行更改 – 这些更改也可以通过a
或b
,因为它们仍然具有对同一对象的引用。
它们就像两张纸,上面写着相同的房屋地址 – 两个变量彼此之间没有任何关系,它们碰巧由于前一行而具有相同的值。
所以,当我们在这一行上更改b
的值时:
b = null;
这只会改变b
的值。 它将b
的值设置为空引用。 这不会对b
的旧值或 String引用的StringBuilder
对象的值进行任何更改。
我有一篇文章详细介绍了这一点 ,你会发现它很有用。
变量b
没有对变量a
的引用,它具有对a引用的StringBuilder
对象的引用。 这就是b=a
作用,它为b
指定了对b
引用的对象的引用。 只要是这种情况,当通过a
使用对象时,通过b
对对象的任何更改都是可见a
。
当b
被赋值为null
,它不再具有对任何对象的引用,但仍然保持其引用。
这是一张描绘这个的图片:
您需要分别考虑引用和对象 。 有一个对象, 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)的用途。
b没有对a的引用。 没有“a”可以参考。 你在内存中有一个对象 (stringbuilder)和两个引用它的不同变量 。 b = a
行在b = a
创建引用的副本并将其分配给b。
当你设置b = a;
,你说的是“ b
指向a
也指向内存的对象”。 所以当你这样做时:
b.Append("b");
这样做完全相同:
a.Append("b");
但它的真正含义(对于a
和b
)是:
[Object memory reference of a and b].Append("b");