About Serializable Dictionary

Hi, i want to put this into json file for saving.

public SerializableDictionary<NFT, List<NFTData>> _collectionsPageNFT;

But when i tried to save getting a error;

FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
System.Text.StringBuilder.AppendFormatHelper (System.IFormatProvider provider, System.String format, System.ParamsArray args) (at <6073cf49ed704e958b8a66d540dea948>:0)
System.String.FormatHelper (System.IFormatProvider provider, System.String format, System.ParamsArray args) (at <6073cf49ed704e958b8a66d540dea948>:0)
System.String.Format (System.String format, System.Object[] args) (at <6073cf49ed704e958b8a66d540dea948>:0)
SerializableDictionary`2[TKey,TValue].OnAfterDeserialize () (at Assets/Scripts/SaveLoad/SerializableDictionary.cs:36)
UnityEngine.JsonUtility:FromJson(String)
SaveLoad:Load() (at Assets/Scripts/SaveLoad/SaveLoad.cs:61)
SaveGameManager:TryLoadData() (at Assets/Scripts/SaveLoad/SaveGameManager.cs:41)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

I think we can’t put list to serializable dictionary. Just want to ask any way to do this.

Also here’s my script to serialize;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
    [SerializeField]
    private List<TKey> keys = new List<TKey>();

    [SerializeField]
    private List<TValue> values = new List<TValue>();

    // save the dictionary to lists
    public void OnBeforeSerialize()
    {
        keys.Clear();
        values.Clear();
        foreach (KeyValuePair<TKey, TValue> pair in this)
        {
            keys.Add(pair.Key);
            values.Add(pair.Value);
        }
    }

    // load dictionary from lists
    public void OnAfterDeserialize()
    {
        this.Clear();

        if (keys.Count != values.Count)
            throw new System.Exception(string.Format("there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable."));

        for (int i = 0; i < keys.Count; i++)
            this.Add(keys[i], values[i]);
    }
}

Have you actually read the error message?

It’s very funny because your exception thrower crashes because you are using {0} and {1} in that string.Format call to address arguments that don’t exist.

This is probably the first time in my life I’ve seen an exception on the actual exception.
It’s like Inception, but Exception lol

1 Like

That’s the why I posted it here. Should I look for another way? Because it seems can’t be solve

Please, you must learn how to use C# properly.

All programming languages are very exact, you can’t make even the slightest mistake. Check out the pinned thread on how to resolve null exceptions; in this case you’ve produce a relatively complicated logical error that is very simple to fix, but if you know next to nothing, you really should go back to basics and learn C#. There are plenty of good resources and tutorials to help you with this.

You can’t just copy/paste if you have so little experience and knowledge about what the code does and expects. You’ll constantly glitch yourself at every step, and seek for help. Who’s making this, you or we?

If you really want to fix this, you need to change this line

throw new System.Exception(string.Format("there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable."));

to this one

throw new System.Exception(string.Format("there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable.", keys.Count, values.Count));

but this will only mark the beginning of your problems.

1 Like