5

So I found out today that structs and classes act differently when used to assign to variables in C#.. It's to my understanding that when I assign a struct to a variable, the variable stores a copy of that struct, and when I assign a class to a variable, the variable stores the reference to that class instance.

In this case, dad2 contains a copy of dad1, so shouldn't anything I do to dad2 not affect dad1? It's not the case apparently because when I add a son to dad2 it also adds the same son to dad1.

public struct Dad {
        public string name;
        public List <Son> sons;

        public struct Son {
            public string name;

            public Son (string n) {
                name = n;
            }
        }
    }

    static void Main (string [] args) {
        Dad dad1 = new Dad ();
        dad1.name = "Bob";
        dad1.sons = new List <Dad.Son> {new Dad.Son ("A")};

        Dad dad2 = dad1;
        Debug.WriteLine (dad2.Equals (dad1) + " " + dad1.sons.Count () + " " + dad2.sons.Count ());
        //true 1 1
        dad2.sons.Add ( new Dad.Son ("B"));
        Debug.WriteLine (dad2.Equals (dad1) + " " + dad1.sons.Count () + " " + dad2.sons.Count ());
        //true 2 2
    }
1

3 Answers 3

4

yes it makes a copy of the values inside the struct - and inside the struct there a reference to a List so that reference gets copied too - that is a "shallow copy"... if the List would have been copied over to a new object this would be a "deep copy"... Struct assignment uses "copy" semantics which depends the copy semantics of each member... see http://msdn.microsoft.com/en-us/library/saxz13w4.aspx

Sign up to request clarification or add additional context in comments.

1 Comment

I see, so right after I declared dad2 I have to redeclare its List and copy the elements from dad1's List.
1

Think of class-type variables and fields as holding "instance ID's" and everything will be clear. Suppose a struct field "Foo" of type List has a value of "Instance ID#95341". Copying the struct will yield another struct whose field "Foo" also holds "Instance ID#95341". Calling Foo.Add on one such struct will add an element to the list referred to by "Instance ID #95341". Querying Foo.Count on the other such struct will get the count from the list referred to by "Instance ID #95341", which will naturally be the same List.

Comments

0

I am answering to this

so shouldn't anything I do to dad2 not affect dad1?"

With your code, any change in the

public List <Son> sons;

is seen in both copies (dad1 and dad2); however any change in

public string name;

is seen only on the object changed

Example - change only the name of dad2 and not the name of dad1

Dad dad1 = new Dad();
dad1.name = "Bob";
dad1.sons = new List<Dad.Son> { new Dad.Son("A") };

Dad dad2 = dad1;
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//true 1 1
dad2.sons.Add(new Dad.Son("B"));
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//true 2 2

dad2.name = "Tom";
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//False 2 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.