Search Unity

Bug Dictionary.Clear() and Dictionary.Remove() do not do anything

Discussion in 'Scripting' started by MinhocaNice, Jan 6, 2022.

  1. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    In my FPS game, I made this code to save the player's binded controls into a dictionary that can be accessed by other scripts later on:

    Code (CSharp):
    1.     public void SaveControls()
    2.     {
    3.         ControlDictionary.Clear();
    4.         foreach (Control CurrentControl in ControlArray)
    5.         {
    6.             ControlDictionary.Add(CurrentControl.Name, CurrentControl.Key);
    7.         }
    8.  
    9.         ControlsCollectionScript.ControlArray = ControlArray;
    10.  
    11.         //Save ControlArray to a .json file//
    12.         string ControlsJSON = JsonUtility.ToJson(ControlsCollectionScript);
    13.         File.WriteAllText(Application.dataPath + "/controls.json", ControlsJSON);
    14.         //Save ControlArray to a .json file//
    15.     }
    However, the script returned this error message:

    ArgumentException: An item with the same key has already been added. Key: System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <9577ac7a62ef43179789031239ba8798>:0) System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <9577ac7a62ef43179789031239ba8798>:0) ControlsManager.SaveControls () (at Assets/Scripts/ControlsManager.cs:228) ControlsManager.ResetAllControls () (at Assets/Scripts/ControlsManager.cs:97) ControlsManager.LoadControls () (at Assets/Scripts/ControlsManager.cs:203) ControlsManager.Awake () (at Assets/Scripts/ControlsManager.cs:24)


    Which is very odd, considering that the very first thing the script does is clear the Dictionary before trying to add any keys to it. I tried using Dictionary.Remove() as well but to no avail:

    Code (CSharp):
    1. public void SaveControls()
    2.     {
    3.         ControlDictionary.Clear();
    4.         foreach (Control CurrentControl in ControlArray)
    5.         {
    6.             ControlDictionary.Remove(CurrentControl.Name);
    7.         }
    8.  
    9.         foreach (Control CurrentControl in ControlArray)
    10.         {
    11.             ControlDictionary.Add(CurrentControl.Name, CurrentControl.Key);
    12.         }
    13.  
    14.         ControlsCollectionScript.ControlArray = ControlArray;
    15.  
    16.         //Save ControlArray to a .json file//
    17.         string ControlsJSON = JsonUtility.ToJson(ControlsCollectionScript);
    18.         File.WriteAllText(Application.dataPath + "/controls.json", ControlsJSON);
    19.         //Save ControlArray to a .json file//
    20.     }
    Finally, I was able to get around this by checking in each individual key if it exists, and got around the problem.

    Code (CSharp):
    1.     public void SaveControls()
    2.     {
    3.         ControlDictionary.Clear();
    4.  
    5.         foreach (Control CurrentControl in ControlArray)
    6.         {
    7.             if (!ControlDictionary.ContainsKey(CurrentControl.Name))
    8.             {
    9.                 ControlDictionary.Add(CurrentControl.Name, CurrentControl.Key);
    10.             }
    11.         }
    12.  
    13.         ControlsCollectionScript.ControlArray = ControlArray;
    14.  
    15.         //Save ControlArray to a .json file//
    16.         string ControlsJSON = JsonUtility.ToJson(ControlsCollectionScript);
    17.         File.WriteAllText(Application.dataPath + "/controls.json", ControlsJSON);
    18.         //Save ControlArray to a .json file//
    19.     }
    But this felt very wrong, as I am very clearly wiping out the Dictionary before using it. What is going on here? Is this just a bug?
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    You can verify that .Clear() is working by outputting ControlDictionary.Count just before the for loop. I guarantee it's working... if it didn't work, about a million projects would be broken.

    I would hazard a guess that two of your controls have the same name. Try outputting each control's name just before they are added - I bet you'll see the same name twice there.
     
    Yoreki and VolodymyrBS like this.