Why do reference types inside structures behave like value types?

I am starting to program in C #. Now I study strings, structs, value typesand reference types. As a response to the received here and there , stringsare reference types, in which the pointers are stored in a stack of their actual content stored on the heap. In addition, as indicated in here , structsare value types. Now I try to practice with structsand stringswith 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);
    }
}

Code snippets above

Person 1
Person 2

. strings , structs , person_1.name person_2.name , ?

+4
4

, , ,

, . , . #. # .

-, , . - . # . . # . .

-, , . , .

.

    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";

, . Person - , , , :

string person_1_name = null; // That 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

person2 = person1, , person1 person2. ( # , .) " person1 person2". - .

, ; , .

+10

. person_1.name - person_2.name. static .

person_2 = person_1 .

, string , .

class, :

class C { public string S; }

C c1 = new C();
C c2 = c1; //copy reference, share object
c1.S = "x"; //it appears that c2.S has been set simultaneously because it the same object

c1.S c2.S . struct, ( ). c2 = c1 struct, .

+7

- , ; , .

? , , (, ) . .

AnyType y = x;, , , x, y.

, x , x y , . x - , x y , .

, , , . :

Person person_1 = new Person();

, . , , , person_1, - . ( ), , , .

person_1.name = "Person 1";

name, person_1. , , name , - , string "Person 1". , , .

Person person_2 = person_1;

, . ? , , person_1, person_2. , person_2. name, , , , person_1.name ( "Person 1").

person_2.name = "Person 2";

person_2.name. , , string - . , person_2.name , person_1.name, , person_2.name, , person_1.name, ... , . , .

, , , Person .

+6

. , .

public struct Lottery
{
    public int[] numbers;
}

public static void Main()
{
    var A = new Lottery();
    A.numbers = new[] { 1,2,3,4,5 };
    // struct A is in the stack, and it contains one reference to an array in RAM

    var B = A;
    // struct B also is in the stack, and it contains a copy of A.numbers reference
    B.numbers[0] = 10;
    // A.numbers[0] == 10, since both A.numbers and B.numbers point to same memory
    // You can't do this with strings because they are immutable

    B.numbers = new int[] { 6,7,8,9,10 };
    // B.numbers now points to a new location in RAM
    B.numbers[0] = 60;
    // A.numbers[0] == 10, B.numbers[0] == 60        
    // The two structures A and B *are completely separate* now.
}

So, if you have a structure containing links (strings, arrays or classes) and you want to implement ICloneable, make sure that you also clone the contents of the links.

public class Person : ICloneable
{
    public string Name { get; set; }

    public Person Clone()
    {
        return new Person() { Name=this.Name }; // string copy
    }
    object ICloneable.Clone() { return Clone(); } // interface calls specific function
}
public struct Project : ICloneable
{
    public Person Leader { get; set; }
    public string Name { get; set; }
    public int[] Steps { get; set; }

    public Project Clone()
    {
        return new Project()
        {
            Leader=this.Leader.Clone(),         // calls Clone for copy
            Name=this.Name,                     // string copy
            Steps=this.Steps.Clone() as int[]   // shallow copy of array
        };
    }
    object ICloneable.Clone() { return Clone(); } // interface calls specific function
}
+3
source

Source: https://habr.com/ru/post/1660582/


All Articles