duong_dajgja duong_dajgja - 26 days ago 15
C# Question

Why reference types inside structs behave like value types?

I am a beginner to C# programming. I am now studying

strings
,
structs
,
value types
and
reference types
. As accepted answers in here and in here,
strings
are reference types that have pointers stored on stack while their actual contents stored on heap. Also, as claimed in here,
structs
are value types. Now I try to practice with
structs
and
strings
with a small example:

struct Person
{
public string name;
}

class Program
{
static void Main(string[] args)
{
Person person_1 = new Person();
person_1.name = "Person 1";

Person person_2 = person_1;
person_2.name = "Person 2";

Console.WriteLine(person_1.name);
Console.WriteLine(person_2.name);
}
}


The above code snippet outputs

Person 1
Person 2


that makes me confused. If
strings
are reference types and
structs
are value types then person_1.name and person_2.name should point to the same space region on heap, shouldn't them?

Answer

strings are reference types that have pointers stored on stack while their actual contents stored on heap

No no no. First off, stop thinking about stack and heap. This is almost always the wrong way to think in C#. C# manages storage lifetime for you.

Second, though references may be implemented as pointers, references are not logically pointers. References are references. C# has both references and pointers. Don't mix them up. There is no pointer to string in C#, ever. There are references to string.

Third, a reference to a string could be stored on the stack but it could also be stored on the heap. When you have an array of references to string, the array contents are on the heap.

Now let's come to your actual question.

    Person person_1 = new Person();
    person_1.name = "Person 1";
    Person person_2 = person_1; // This is the interesting line
    person_2.name = "Person 2";

Let's illustrate what the code does logically. Your Person struct is nothing more than a string reference, so your program is the same as:

string person_1_name = null; // That's what new does on a struct
person_1_name = "Person 1";
string person_2_name = person_1_name; // Now they refer to the same string
person_2_name = "Person 2"; // And now they refer to different strings

When you say person2 = person1 that does not mean that the variable person1 is now an alias for the variable person2. (There is a way to do that in C#, but this is not it.) It means "copy the contents of person1 to person2". The reference to the string is the value that is copied.

If that's not clear try drawing boxes for variables and arrows for references; when the struct is copied, a copy of the arrow is made, not a copy of the box.