1

I have two dictionaries. When I change a value in dictionary 1, the same change appears in dictionary 2. How do I change a value only in dictionary 1, not in dictionary 2 as well?

   List<Dictionary<string, string>> ld1 = new List<Dictionary<string, string>>();
   Dictionary<string, string> d1 = new Dictionary<string,string>();

   d1.Add("Text", "Value1");
   d1.Add("Format", "Value2");
   ld1.Add(d1);

   List<Dictionary<string, string>> ld2 = new List<Dictionary<string, string>>(ld1);
   // ld2 = ld1

   ld1[0]["Text"] = "Eulav";        // should: change only in the first dictionary
                                    // actually: changes in the second dictionary as well

   Console.WriteLine(ld1[0]["Text"]);
   Console.WriteLine(ld2[0]["Text"]);

Outputs

Eulav
Eulav
dave4420
  • 46,404
  • 6
  • 118
  • 152
Radicz
  • 145
  • 1
  • 9

4 Answers4

3

You only create a new list but the items in that list reference the same objects (dictionaries), so you need to create a copy of each item as well:

var ld2 = new List<Dictionary<string, string>>();

foreach (var dict in ld1)
{
    ld2.Add(new Dictionary<string, string>(dict));
}
ChrisWue
  • 18,612
  • 4
  • 58
  • 83
3

If you want to have two shallow copies of a particular Dictionary<TKey, TValue> then just use the constructor to create a copy

Dictionary<string, string> ld1 = ...;
Dictionary<string, string> ld2 = new Dictionary<string, string>(ld1);

Note: In this particular case it will be a deep copy since string is immutable and has no child data which needs to be deeply copied

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

The point to remember here is that though you are creating two instances (Two distinct memory allocations) of List, you are only creating "one" instance of Dictionary.

Thus, both the lists have the same memory pointer, pointing to the same dictionary. And it is obvious that the change in one will update the other too.

As suggested by others, here you need to create one more instance of Dictinary (A distinct memory allocation) and copy the values of the first one to it.

Dictionary<string, string> ld2 = new Dictionary<string, string>(ld1);

Doing this will store different instances in list and changes in one will not effect other.

Manish Basantani
  • 16,931
  • 22
  • 71
  • 103
1

user1158781 in order do it with non inmutable objects like strings, you will have to clone every element of the dictionary to a new one.

You can implement the IClonable interface. I leave a litle example:

 class Program
{
    static void Main(string[] args)
    {
        Dictionary<int, Person> dic1 = new Dictionary<int, Person>();
        dic1.Add(0, new Person { Name = "user1158781" });
        Dictionary<int, Person> dic2 = new Dictionary<int, Person>();
        foreach (var item in dic1)
        {
            dic2.Add(item.Key, (Person)item.Value.Clone());
        }

        dic1[0].Name = "gz";

        Console.WriteLine(dic1[0].Name);
        Console.WriteLine(dic2[0].Name);
    }

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

        public object Clone()
        {
            return new Person { Name = this.Name };
        }
    }
}
Guido Zanon
  • 2,939
  • 26
  • 31