0

I thought I understood the difference between Reference and Value types. I thought that 'string' only had value-type semantics while retaining the behavior of reference types. Then I tried this, expecting to see True returned in both cases. What have I misunderstood?

        string strA = "AAA";
        string strB = strA;
        strB = "BBB";
        Console.WriteLine($"strA is {strA} and strB is {strB}");
        Console.WriteLine($"The statement: strA == strA is {strA == strB} \n");

        Car car1 = new Car();
        car1.Horsepower = 190;
        Car car2 = car1;
        car2.Horsepower = 200;
        Console.WriteLine($"car1.Horsepower is {car1.Horsepower} and car2.Horsepower is {car2.Horsepower}");
        Console.WriteLine($"The statement: car1 == car2 is {car1 == car2}");

Output:

strA is AAA and strB is BBB

The statement: strA == strA is False

car1.Horsepower is 200 and car2.Horsepower is 200

The statement: car1 == car2 is True

maccettura
  • 10,514
  • 3
  • 28
  • 35
PakiPat
  • 1,020
  • 14
  • 27
  • Once a string value is set, it points to that location in memory. it can never change. If you set a new value, you actually get a new pointer to a different location in memory holding the new value. If you want this behavior, try it with a string builder. StringBuilder builderA = new StringBuilder("AAA"); StringBuilder builderB = builderA; builderB.Replace("AAA", "BBB"); Console.WriteLine($"builderA is {builderA.ToString()} and builderB is {builderB.ToString()}"); – Aaron Sep 28 '17 at 20:03
  • @Aaron: Ah. I got that strings in C# are immutable. I guess I didn't square that against the idea that when we change a value, the pointer changes. Thanks for the insight into StringBuilder. I would mark this comment as the Answer if I could. – PakiPat Sep 28 '17 at 23:19
  • Is it safe to say, then, that the only aspect of a string that is common to other 'pure' references types is that it's saved in the heap rather than the stack? – PakiPat Sep 28 '17 at 23:25

1 Answers1

2

String literals designate string instances. Converting strings to cars to facilitate, this is basically what you're doing with strings:

Car AAA = new Car();
Car BBB = new Car();

Car carA = AAA;
Car carB = carA;
carB = BBB;
Console.WriteLine($"carA is {carA} and carB is {carB}");
Console.WriteLine($"The statement: carA == carB is {carA == carB}

The big difference is that you use "string literals" instead of new Car/new String because the compiler pre-allocates objects for static strings.

zneak
  • 134,922
  • 42
  • 253
  • 328