Сериализация Исключение: не удалось найти тип 'System.Collections.Generic.List`1 в С# unity3d

Я пытаюсь сериализовать и десериализовать объект в С# unity3d. Для этого я использую приведенный ниже код. Но я получаю ошибку, упомянутую ниже.

Ошибка: Сериализация Исключение: не удалось найти тип "System.Collections.Generic.List`1 [[ABC, Assembly-CSharp, Version = 1.0.2.18931, Culture = neutral, PublicKeyToken = null] ]".

Это не происходит, когда я сериализую объект save в файл и загружаю его из файла, пока я играю в игру, не останавливая игру.

Но ошибка возникает, если я останавливаю игру и меняю любую строку кода (не относящуюся к сериализации и десериализации) и загружаю данные из файла, сохраненного ранее, и пытается десериализовать. Я получаю SerializationException.

Я использую редактор визуальной студии, а версия single3d - 5.5.4.

Возможно, мне не хватает чего-то очень простого. может кто-то помочь мне в решении этого вопроса.

Спасибо.

public static string SerializeObject<T>(T objectToSerialize)
{
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream memStr = new MemoryStream();

    try
    {
        bf.Serialize(memStr, objectToSerialize);
        memStr.Position = 0;

        return Convert.ToBase64String(memStr.ToArray());
    }
    finally
    {
        memStr.Close();
    }
}

public static T DeserializeObject<T>(string str)
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Binder = new CurrentAssemblyDeserializationBinder();
    byte[] b = Convert.FromBase64String(str);
    MemoryStream ms = new MemoryStream(b);

    try
    {
        return (T)bf.Deserialize(ms);
    }
    finally
    {
        ms.Close();
    }
}

Класс, который я использую:

    [Serializable]

  public class ABC : ISerializable
  {
    public SerializableDictionary<int, ExampleClass> a = new SerializableDictionary<int, ExampleClass>();

    public GameObject b;
    public GameObject c;
    public bool d = false;
    public ABC e;
    public int f;
    public string g = "";
    public int h = -1;
    public int i = -1;
    public int j = -1;
    public string k = "default";
    public XYZ l = XYZ.P;
  }

    [Serializable]
    public enum XYZ
    {
        P,
        Q
    }


    [Serializable()]
    public class ABCListWrapper : ISerializable
    {

    public List<ABC> abcMappings = new List<ABC>();
    public string version = "1.53";
    public float interval;
    }


    //Serilization 
    abcLW = new ABCListWrapper();
    abcW = getABCListWObj();
    string abcWString = SerializeObject(abcW);
    File.WriteAllText(Application.streamingAssetsPath + "/filename.json", abcWString);


    //Deserilization call 
    ABCListWrapper l = new ABCListWrapper();
    string l_1 = File.ReadAllText(Application.streamingAssetsPath + "/filename.json");
    l =  DeserializeObject<ABCListWrapper>(l_1);

Попытка решить проблему:

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        Version assemVer1 = Assembly.GetExecutingAssembly().GetName().Version;
        Debug.Log("ASSEM VER: " + assemVer1 + "--NAME--" + assemblyName + " --OVERAL-- " + Assembly.GetExecutingAssembly().FullName + " --TYPE-- " + typeName );
        //assemblyName = Assembly.GetExecutingAssembly().FullName.Replace(assemVer1.ToString(), "1.0.2.23455");
        //string assemblyNameCustom = "Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null";

        bool isList = false;

        if (typeName.Contains("List`1"))
            isList = true;
        // other generics need to go here

        if (isList)
            return Type.GetType(string.Format("System.Collections.Generic.List`1[[{0}, {1}]]", "ABC", "Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null"));
        else
            return Type.GetType(string.Format("{0}, {1}", assemblyName, typeName));

    }

}

Но я получаю такое же исключение, и журнал BindToType никогда не печатается. Таким образом, это означает функцию BindToType в SerilizationBinder.

Ответы

Ответ 1

Бинарный форматтер хранит информацию о версии сборки вместе с сериализованным типом. Таким образом, даже когда тип не изменяется, сериализация/десериализация меняются сразу после обновления сборки.

См. этот связанный Q/A для деталей: Двойная десериализация с другой версией сборки и релевантная Статья MSDN.

Обычно я хотел бы закрыть это как дубликат, но я не могу из-за открытой щедрости, поэтому я решил ответить вместо этого;)

Ответ 2

Для быстрой двоичной сериализации Буферы протоколов могут быть хорошим вариантом. Также он должен разрешать проблемы совместимости (вы можете контролировать порядок/исключение полей вручную)