2017-09-09 73 views
14

Próbuję serializować i deserializować obiekt w C# unity3d. Do tego używam poniższego kodu. Ale pojawia się błąd wspomniany poniżej.SerializationException: Nie można znaleźć typu "System.Collections.Generic.List`1 w C# unity3d

Error: SerializationException: Could not find type 'System.Collections.Generic.List`1[[ABC, Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null]]'.

To się nie dzieje, a ja serializacji obiektu zapisać do pliku i załadować go z pliku, a ja gram grę na zatrzymanie gry.

Ale błąd występuje, gdy zatrzymam grę i zmienię linię kodu (nieistotną dla serializacji i Deserializacji) i wczytam dane z pliku zapisanego poprzednio i próbę deserializacji Otrzymuję SerializationException.

Używam edytora Visual Studio oraz wersję Unity3D jest 5.5.4

I może być brakuje czegoś bardzo prostą rzecz. Czy ktoś mógłby mi pomóc w rozwiązaniu tego problemu?

Dzięki.

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(); 
    } 
} 

klasa używam:

[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); 

Próba rozwiązania problemu:

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)); 

    } 

} 

Ale ja dostaję ten sam wyjątek i dziennik w BindToType nigdy nie zostanie wydrukowany. Oznacza to więc funkcję BindToType w BindToType w BindToType.

+0

Opublikuj klasę, której próbujesz użyć. Pokaż także, w jaki sposób wywołujesz te funkcje i gdzie występuje błąd. – Programmer

+0

jest jakikolwiek sposób, w jaki jestem wysyłany do ciebie prywatnie, ponieważ jest to zasób innej firmy, którego używam i nie mogę go bezpośrednio opublikować tutaj – djkp

+0

Nie proszę o plik. Klasa, którą próbujesz serizele/deserialize i jak używasz tych dwóch funkcji na tej klasie – Programmer

Odpowiedz

9

Formater binarny przechowuje informacje o wersji zespołu razem z typem szeregowym. Więc nawet jeśli typ nie zostanie zmieniony, serializacja/deserializacja zmienia się natychmiast po zaktualizowaniu zespołu.

Zobacz szczegółowe informacje na ten temat: Binary Deserialization with different assembly version i the relevant MSDN article.

Normalnie bym zamknąć-głosowanie to jako duplikat, ale nie mogę z powodu otwartej laski, więc postanowiłem odpowiedzieć zamiast;)

+0

Edytował pytanie przy próbie rozwiązania problemu, który daje ten sam błąd, spójrz na to – djkp

+0

@djkp Gdzie używasz 'CurrentAssemblyDeserializationBinder'? 'Bf.Binder = new CurrentAssemblyDeserializationBinder() 'nie znajduje się w zaktualizowanym kodzie. – grek40

+0

Przepraszam, że mój błąd podczas aktualizacji dodałem, dziękuję :) – djkp

0

Do szybkiego binarnym serializacji Protocol Buffers może być dobrym rozwiązaniem. Powinien również rozwiązać problemy ze zgodnością (możesz ręcznie kontrolować kolejność/wykluczanie pól).

+0

Ale bufory protokołów nie działają z typem danych jedności typu "GameObject", czy próbowałeś go za pomocą połączenia podanego przeze mnie – djkp