5

I was wondering when and why references get broken in C#?

The following code example highlights this:

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

Why is it, for this example, that b's reference to a does not cause a to be null as well?

Widor
  • 13,003
  • 7
  • 42
  • 64
Joey Ciechanowicz
  • 3,345
  • 3
  • 24
  • 48
  • 1
    Read this: http://stackoverflow.com/questions/5057267/difference-between-reference-type-and-value-type-in-c-sharp/5057284#5057284 – xanatos Oct 18 '11 at 13:14
  • 1
    Important to understand the difference between reference and value types in .NET programming. Any decent book talks about it. – Hans Passant Oct 18 '11 at 13:19

5 Answers5

13

You need to distinguish between variables, references and objects.

This line:

b = a;

sets the value of b to the value of a. That value is a reference. It's a reference to an object. At this point, making changes to that object via either a or b will just make changes to the same object - those changes would be visible via either a or b too, as both still have references to the same object.

They're like two pieces of paper with the same house address written on them though - the two variables don't know anything about each other, they just happen to have the same value due to the previous line.

So, when we change the value of b on this line:

b = null;

that just changes the value of b. It sets the value of b to a null reference. This makes no changes to either the value of a or the StringBuilder object which the old value of b referred to.

I have an article which goes into more details on this, and which you may find useful.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
11

Variable b does not have a reference to variable a, it has a reference to the StringBuilder object referred to by a. That's what b=a does, it assigns to b a reference to the object referred to by a. As long as this is the case, any changes to the object via b are visible when the object is used via a.

When b gets assigned null, it no longer has a reference to any object, but a still maintains its reference.

Here is a picture depicting this:

References

Adaline Simonian
  • 4,596
  • 2
  • 24
  • 35
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
7

You need to think separately about the reference and the object. There is one object, the StringBuilder. A reference is essentially the memory location of the object (give or take some notional abstraction), with a value of some large integer. You have two references variables.

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

Also note that even if we add

a = null; // both variables empty

we still have 2 empty variables and one object; the object doesn't magically disappear - that is what garbage collection (GC) is for.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
6

b doesn't have a reference to a. There is no "a" to refer to. You have an object in memory (the stringbuilder) and two different variables that refer to it. The line b = a makes a copy of the reference in a and assigns it to b.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
2

When you set b = a;, you are saying "b points to the object that a also points to in memory." So when you do this:

b.Append("b");

Doing this is the exact same thing:

a.Append("b");

But what it really is (for both a and b) is:

[Object memory reference of a and b].Append("b");

qJake
  • 16,821
  • 17
  • 83
  • 135
  • I don't think the last part of your answer is quite right and could be confusing, I would rephrase it say that `b.Append("b")` is the equivalent of `a.Append("b")` as both references point to the same object. – Andy Rose Oct 18 '11 at 13:19