Search code examples
c#.netstringstringbuilderreference-type

.NET strings and reference type parameters


How does the following code work?

public void SomeMethod()
{
    StringBuilder sb = new StringBuilder();
    AppendFoo(sb);
    String foo = sb.ToString(); // foo is "foo"

    String s = String.Empty;
    AppendBar(s);
    String bar = s; // bar is empty 
}

public void AppendFoo(StringBuilder x)
{
    x.Append("Foo");
}

public void AppendBar(String x)
{
    x = x + "Bar";
}

If both StringBuilder and String are reference types, why is the string object not altered when passing it through the AppendBar method, whereas the StringBuilder object is altered when passing it into the AppendFoo method, as the both parameters to the methods are taking reference types as parameters?


Solution

  • Ignore the fact that strings are immutable for the moment - it's a bit of a red herring. The important point is the difference between:

    x.Append(...);
    

    and

    x = x + ...;
    

    Look at them closely: the first one is acting on the object that x refers to, changing the contents of the StringBuilder. The second is changing the value of x to refer to a different object (a new string). It's not changing the contents of the existing object. (In fact it couldn't because strings are immutable, but the same logic would apply anyway.)

    Changing the value of x within a method doesn't change the value of the argument used to initialize x.

    The crucial point is to differentiate between changing the value of a variable and changing the contents of the object it refers to. Once you've got that difference, the rest should fall into place.

    Read more about this and parameters in my article on parameter passing, and more about reference types vs value types in another article.