String reference in C#

Viewed 155

As string is ref type in dotnet, when we update variable x, there should be update in y too ? (as it is referring value of x). sample program given below, how value of y is not changing when x is updated?

public void assignment()
{
    string x= "hello";
    string y=x; // referencing x as string is ref type in .net
    x = x.Replace('h','j');
    Console.WriteLine(x); // gives "jello" output
    Console.WriteLine(y); // gives "hello" output 
}
3 Answers

You are right that, initially, both x and y reference the same object:

       +-----------+
y   -> |   hello   |
       +-----------+
            ^
x   --------+

Now have a look at this line:

x = x.Replace('h','j');

The following happens:

  1. x.Replace creates a new string (with h replaced by j) and returns a reference to this new string.

           +-----------+    +------------+
    y   -> |   hello   |    |   jello    |
           +-----------+    +------------+
                ^
    x   --------+
    
  2. With x = ..., you assign x to this new reference. y still references the old string.

           +-----------+    +------------+
    y   -> |   hello   |    |   jello    |
           +-----------+    +------------+
                                  ^
    x   --------------------------+
    

So how do you modify a string in-place? You don't. C# does not support modifying strings in-place. Strings are deliberately designed as an immutable data structure. For a mutable string-like data structure, use StringBuilder:

var x = new System.Text.StringBuilder("hello");
var y = x;

// note that we did *not* write x = ..., we modified the value in-place
x.Replace('h','j');

// both print "jello"
Console.WriteLine(x);
Console.WriteLine(y);

There are already good answers here why this happens. If you however want both to print "jello" you can assign x to y by reference using the ref keyword.

string x = "hello";
ref string y = ref x;
x = x.Replace('h', 'j');
Console.WriteLine(x); // gives "jello" output
Console.WriteLine(y); // gives "jello" output 

More info on Ref locals here.

The string returned is a NEW string reference. In regard of string.Replace() the MSDN says:

"This method does not modify the value of the current instance. Instead, it returns a new string in which all occurrences of oldValue are replaced by newValue"

https://docs.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-5.0.

As mentioned by @Heinzi - strings are immutable and most of the actions taken on strings result in new strings:

"String objects are immutable: they cannot be changed after they have been created. All of the String methods and C# operators that appear to modify a string actually return the results in a new string object"

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#:~:text=String%20objects%20are%20immutable%3A%20they,in%20a%20new%20string%20object.

Cheers!

Related