0

I have a simple conceptual question in C#. In C# strings are reference types. So this mean when I create a string variable 'ABC' it will only contain the reference or address to the actual character Array on the managed heap.

So, If I write:

string ABC = "Hye";
String XYZ = ABC;
ABC = ABC.Replace("H","B");

Console.WriteLine("ABC - "+ ABC);
Console.WriteLine("XYZ - "+ XYZ);

Actual Output is:

 ABC - Bye
 XYZ - Hye

But I expected this to be Bye in both cases as I thought XYZ would also be pointing to the same address as ABC and any changes in ABC will be refecting in XYZ.

Can anyone tell me where I am wrong?

Mac Ank
  • 51
  • 1
  • 6
  • The answer to this question is "because string is immutable in .NET". That prompts the next question - why are they immutable? - which is answered in the link above. – Yuck Feb 02 '15 at 13:34
  • 2
    @aloisdg: It's prefectly reasonable to expect that a change in the string would be seen from both variables, as that is exactly what would happen. What's missing in the reasoning is that strings are immutable, so there won't be any change in the string. – Guffa Feb 02 '15 at 13:35

3 Answers3

5

Let's look at your code line by line;

string ABC = "Hye";

With this line, you created string object as "Hye" and a reference to that object called ABC.

enter image description here

String XYZ = ABC;

With this line, you created a reference called XYZ and this reference referring the same object with ABC reference, which is "Hye"

enter image description here

ABC = ABC.Replace("H","B");

Since strings are immutable types, String.Replace() method doesn't change the original object. It returns a new object and your ABC reference referring that object which is "Bye". It doesn't referring the old object anymore.

enter image description here

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
3

I think that this line:

ABC = ABC.Replace("H","B");

creates new instance of String. From MSDN: 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.

Info - MSDN

Marcin
  • 821
  • 12
  • 20
2

Short version: No it shouldn't be pointing to the same address. It was pointing to the same address but you replaced the address in ABC with another (the result of the replace).

Long version

Think of it this way - the assignment operator (=) as well as passing arguments to a method and returning values from a method always does a copy. The difference between reference types and value types is what is copied. When the value is a value type the whole data in memory is copied to another place in memory. The variable itself contains the data. When working with reference types the variable (aslo method argument and method return value) holds the address of the object in memory. This is why when you assign one variable to another they point to the same object. Both variables store the same address. However the = operator still does a copy from one variable to the other. It copies the address. Therefore when you assign the return value from the replace method you copy the address of the new string in the variable ABC. You do not copy anything in the other variable. They used to point to the same object but now they don't because the address copied in ABC is now different. Variables of reference types are not linked by some magic they are linked by the fact that they hold addresses of the same object but the addresses themselves are just numbers. If you use the = operator on the variable you replace the object. If you change the object the value will change in both variables but if you replace the object the variables will hold different objects.

Note that this holds true for method arguments too.

List<string> list = new List<String> { "asdf" };
SomeMethod(list);
//list contains "asdf", "fdsa"
SoemOtherMethod(list),
//list is NOT null

static void SomeMethod(List<string> list)
{
    list.Add("fdsa"); //changes the original list
}

static void SomeOtherMethod(List<string> list)
{
    list = null; //cannot replace the original list only replaces the address in the argument variable
}
Stilgar
  • 22,354
  • 14
  • 64
  • 101
  • Okay, as far as I understand from your comment. [ABC = ABC.Replace("H","B")] , creates another character array in the heap and now ABC point to it instead of the original reference. Am I correct? – Mac Ank Feb 02 '15 at 13:37
  • Yes you are. strings in .NET cannot change (normally without serious hacking). All methods that change strings like replace create a new string object with the changes applied. – Stilgar Feb 02 '15 at 13:51