OnBeforeSerialize not called for class member

Serialisation code that worked in 5.4.? broke when I updated to 5.5.1f1

OnBeforeSerialize gets called for CardSaveData but not for CardSaveData.m_stateGUIDMap

[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 = new List<TKey>(this.Keys);
        values = new List<TValue>(this.Values);
    }

    // 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]);
        keys = null;
        values = null;
    }
}

[System.Serializable]
public class CardSaveData : System.Object, ISerializationCallbackReceiver
{
    [System.Serializable]
    private class GUIDMap : SerializableDictionary<string, string>
    {
    }

    [SerializeField]
    private string m_cardGUID;
    [SerializeField]
    private string m_sceneLocationGUID;
    [SerializeField]
    private GridCoords m_cardCoords;
    [SerializeField]
    private GUIDMap m_stateGUIDMap;
    [SerializeField]
    private List<string> m_underCardGUIDs;
    [SerializeField]
    private List<string> m_overCardGUIDs;
    [SerializeField]
    private bool m_isInPlay;

    // transient state

    private PatchworkProject m_project;

    //Unity serialization does not support null objects so we need to jump through some hoops...
    public void OnBeforeSerialize()
    {
        if (m_cardCoords == null)
        {
            m_cardCoords = new GridCoords(double.NaN, double.NaN);
        }
        if (m_sceneLocationGUID == null)
        {
            m_sceneLocationGUID = "";
        }
    }

    public void OnAfterDeserialize()
    {
        if (!m_cardCoords.Valid())
        {
            m_cardCoords = null;
        }
        if (string.IsNullOrEmpty(m_sceneLocationGUID))
        {
            m_sceneLocationGUID = null;
        }
    }

//Body of this class removed
//...

}

I just built a minimal example of a private inner subclass of a an ISerializationCallbackReceiver using generics and both before and after hooks seem to be working in 5.5 for me.

If you can build a minimal example project that reproduces the issue you’re seeing submit it as a bug.

Generally though, I’d avoid upgrading mid project unless there was a critical fix in the update that I needed.

Found the bug for it. Looks like it’s fixed in the next version.

1 Like

Turns out that it’s not fixed. At least not in 5.5.1.p3. I made another bug report: https://fogbugz.unity3d.com/default.asp?879989_o1n0o3pk06433jca
We worked around it by not deriving from Dictionary and instead IEnumerable

1 Like