Why String is Value type although it is a class not a struct?

user586399 picture user586399 · Sep 2, 2011 · Viewed 11.2k times · Source

Take the following example:

string me = "Ibraheem";
string copy = me;
me = "Empty";
Console.WriteLine(me);
Console.WriteLine(copy);

The output is:

Empty
Ibraheem

Since it is class type (i.e. not a struct), String copy should also contain Empty because the = operator in C# assigns reference of objects rather than the object itself (as in C++)??

Answer

Adam Robinson picture Adam Robinson · Sep 2, 2011

While the accepted answer addresses this (as do some others), I wanted to give an answer dedicated to what it seems like you're actually asking, which is about the semantics of variable assignment.

Variables in C# are simply pieces of memory that are set aside to hold a single value. It's important to note that there's no such thing as a "value variable" and a "reference variable", because variables only hold values.

The distinction between "value" and "reference" comes with the type. A Value Type (VT) means that the entire piece of data is stored within the variable.

If I have an integer variable named abc that holds the value 100, then that means that I have a four-byte block of memory within my application that stores the literal value 100 inside it. This is because int is a value type, and thus all of the data is stored within the variable.

On the other hand, if I have a string variable named foo that holds the value "Adam", then there are two actual memory locations involved. The first is the piece of memory that stores the actual characters "Adam", as well as other information about my string (its length, etc.). A reference to this location is then stored within my variable. References are very similar to pointers in C/C++; while they are not the same, the analogy is sufficient for this explanation.

So, to sum it up, the value for a reference type is a reference to another location in memory, where the value for a value type is the data itself.

When you assign something to a variable, all you're changing is that variable's value. If I have this:

string str1 = "foo";
string str2 = str1;

Then I have two string variables that hold the same value (in this case, they each hold a reference to the same string, "foo".) If then do this:

str1 = "bar";

Then I have changed the value of str1 to a reference to the string "bar". This doesn't change str2 at all, since its value is still a reference to the string "foo".