2

This goes against what I thought I understood about copying a Dictionary. Say, I have the following code:

public class MyClass
{
    public string str1;

    public MyClass(string s)
    {
        str1 = s;
    }
}

Dictionary<string, MyClass> dic1 = new Dictionary<string, MyClass>();
dic1.Add("0", new MyClass("hello"));

//Make 'dic2' as a copy of 'dic1'
Dictionary<string, MyClass> dic2 = new Dictionary<string, MyClass>(dic1);

//Alter 'dic1'
dic1.ElementAt(0).Value.str1 += "!!!";

//I was expecting dic2 not to be altered, but IT IS!
Debug.Assert(dic2["0"].str1.Equals(dic1["0"].str1, StringComparison.Ordinal) == false);     //Result is true for equality

I was expecting that changing a copied dictionary I would not change the original one, but that is not the case with my code.

What am I doing wrong?

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • 2
    Google hint: `shallow copy` versus `deep copy`. You are copying references, not the actual objects. – Corak Apr 11 '13 at 10:17
  • You can read Jon Skeets article about [parameter passing](http://www.yoda.arachsys.com/csharp/parameters.html), which explains references as well. – default Apr 11 '13 at 10:21
  • @Default: I just wish it was better documented. I started using this method after having searched for "C# copy dictionary" thinking that my entire dictionary is copied. – c00000fd Apr 11 '13 at 10:23
  • well, I'm not sure what you have read :) For me it feels natural that the references are copied, but I come from one background of programming and you another. Maybe those who wrote the documentation you read figured that the reader know that references are copied as references. – default Apr 11 '13 at 10:27

1 Answers1

3

As Corak says, you've made a shallow copy. You are copying references to objects in memory, not the objects themselves. Now, for each key, you have two references to one object.

What you want is a deep copy, see here: What is the best way to clone/deep copy a .NET generic Dictionary<string, T>?

Community
  • 1
  • 1
Joe
  • 46,419
  • 33
  • 155
  • 245
  • Thanks. Although it is somewhat confusing. Obviously dictionaries can be nested, so what if I do "shallow copy" on the parent dictionary when the "nested" dictionary does "deep copy"? – c00000fd Apr 11 '13 at 10:24
  • Dictionaries just map keys to values. The values are references not objects, it's just the way that C# works. The values could be structs, in which case they could behave differently (although it's been years, I'm bit hazy). – Joe Apr 11 '13 at 10:27
  • As for nested dictionaries, I think you have to implement your own copying methods. – Joe Apr 11 '13 at 10:28
  • Yeah, I have to do it myself, because that code sample that you linked to doesn't work in my case with a value as my own class. – c00000fd Apr 11 '13 at 10:30
  • I'm sorry that implementation doesn't work for you. But if you are implementing your own classes and use them in this way, it's your responsibility to implement the clone functionality. Good luck! – Joe Apr 11 '13 at 13:00