3

I am using a dictionary within a dictionary. The last key value assigned is getting stored as values for all previous keys as well, even though the individual key assignments are different. Am I missing something?

Dictionary<string, Dictionary <int,bool>> seenValsRounds= new Dictionary<string, Dictionary<int, bool>>();

void prepareRoundsVals()
    {       
        Dictionary <int,bool> roundVals = new Dictionary<int, bool> ();
        roundVals.Add (0,false);
        seenValsRounds.Add ("A", roundVals);
        seenValsRounds.Add ("B", roundVals);
        seenValsRounds.Add ("C", roundVals);
        seenValsRounds.Add ("D", roundVals);
        seenValsRounds ["A"] [0] = false;
        seenValsRounds ["B"] [0] = false;
        seenValsRounds ["C"] [0] = false;
        seenValsRounds ["D"] [0] = true;
        foreach (KeyValuePair<string, Dictionary<int,bool>> kvp in seenValsRounds) {            
            Debug.Log(kvp.Key + " in round " + 0 + ": " + seenValsRounds [kvp.Key][0]);     
        }
    }

Expected Results: A is false, B is false, C is false, D is True

Actual Results: A is True, B is True, C is True, D is True


Solved below as per suggestions from answers and comments. Each nested dictionary should also be 'new':

        Dictionary <int,bool> roundVals1 = new Dictionary<int, bool> ();
        Dictionary <int,bool> roundVals2 = new Dictionary<int, bool> ();
        Dictionary <int,bool> roundVals3 = new Dictionary<int, bool> ();
        Dictionary <int,bool> roundVals4 = new Dictionary<int, bool> ();
        roundVals1.Add (0,false);
        roundVals2.Add (0,false);
        roundVals3.Add (0,false);
        roundVals4.Add (0,false);
        seenValsRounds.Add ("A", roundVals1);
        seenValsRounds.Add ("B", roundVals2);
        seenValsRounds.Add ("C", roundVals3);
        seenValsRounds.Add ("D", roundVals4);
4
  • 3
    You are adding the same Dictionary, roundVals, four times, to seensValsRounds. In your code, there are only two different Dictionaries at play, since you are only doing two "new". Commented May 7, 2019 at 13:18
  • You have one object. you put in in different box. Paint this object in green. The green object can be find in any of those box. Commented May 7, 2019 at 13:24
  • There must be a dupe about ref type and value type somewhere with a basic List<t> Commented May 7, 2019 at 13:26
  • Eric Lippert gave a great answer explaining references in C#, which is what you're running into here. I'm not sure what the best approach for your issue is (e.g., maybe refactor the nested dictionary into something else? Or just clone/copy the Dictionaries as needed), but the root cause is that Dictionary is a reference type. Commented Jun 22, 2021 at 14:59

2 Answers 2

3

Thats because you put the same reference to the roundVals dictionary object in the seenValsRounds dictionary. You should create a new dictionary for A, B, C and D.

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

Comments

0

It's may be helpful or Nested dictionary alternative.

Create Sample.cs script and test it.

 public Dictionary<string,Tuple<string,string,string,int>> _planets = new 
     Dictionary<string, Tuple<string,string, string, int>>();
     void Start()
     {
           string myKey = string.Concat("1","MetalMine","Level");
           if(!_planets.ContainsKey(myKey))
           {
               _planets.Add(myKey,Tuple.Create("1","MetalMine","Level",0));
           }
           Debug.Log("_planets mykey "+myKey+" ==> "+_planets[myKey].Item4);
     }

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.