SerializationException:在 c# unity3d 中找不到类型'System.Collections.Generic.List`1

Posted

技术标签:

【中文标题】SerializationException:在 c# unity3d 中找不到类型\'System.Collections.Generic.List`1【英文标题】:SerializationException: Could not find type 'System.Collections.Generic.List`1 in c# unity3dSerializationException:在 c# unity3d 中找不到类型'System.Collections.Generic.List`1 【发布时间】:2018-02-18 00:31:43 【问题描述】:

我正在尝试在 c# unity3d 中序列化和反序列化一个对象。为此,我正在使用以下代码。但我收到下面提到的错误。

错误: SerializationException: 找不到类型 'System.Collections.Generic.List`1[[ABC, Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null] ]'。

当我在玩游戏而不停止游戏时序列化对象保存到文件并从文件加载它时,不会发生这种情况。

但如果我停止游戏并更改任何代码行(与序列化和反序列化无关)并从先前保存的文件中加载数据并尝试反序列化,则会出现错误我得到一个SerializationException

我使用的是visual studio编辑器,unity3d版本是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 中的日志从未打印出来。所以它表示SerilizationBinder中的函数BindToType

【问题讨论】:

请发布您尝试使用的课程。还要说明您是如何调用这些函数的以及发生错误的位置。 有什么方法可以私下向您发送文件,因为它是我使用的第 3 方资产,我不能直接在此处发布 我不是要文件。您正在尝试 serizele/deserialize 的类以及您如何在此类中使用这两个函数 我添加了调用和类结构 原因是序列化后的memStr和反序列化前的ms不一样。你能调试和比较memStrms吗? 【参考方案1】:

二进制格式化程序将程序集版本信息与序列化类型一起存储。所以即使类型没有改变,序列化/反序列化也会随着程序集的更新而改变。

详情请参阅此相关问答:Binary Deserialization with different assembly version 和 the relevant MSDN article。

通常我会将此作为重复投票,但由于开放赏金我不能,所以我决定改为回答;)

【讨论】:

编辑了这个问题,试图解决这个问题,它给出了同样的错误,请查看它 @djkp 你在哪里使用CurrentAssemblyDeserializationBinderbf.Binder = new CurrentAssemblyDeserializationBinder() 不在您更新的代码中。 对不起,我在更新时出错了,我添加了它,谢谢:) @djkp 我无法用您的实际对象对此进行测试,因为它未完全提供(缺少ExampleClassGameObjectSerializableDictionary,缺少ISerializable 的实现,...)但对我来说,BindToType 被要求参加一个小型测试课程。也许您可以先用更简单的类型测试该方法,然后找出复杂类的哪一部分正在发挥作用。 这发生在同一个项目中,甚至没有在一个项目中序列化并在另一个项目中反序列化。【参考方案2】:

对于快速二进制序列化Protocol Buffers 可能是不错的选择。它还应该解决兼容性问题(您可以手动控制字段顺序/排除)

【讨论】:

但是 Protocol Buffers 不能使用统一的GameObject 数据类型,你用我提供的调用试过了吗

以上是关于SerializationException:在 c# unity3d 中找不到类型'System.Collections.Generic.List`1的主要内容,如果未能解决你的问题,请参考以下文章

使用谓词列表时出现 DataContract SerializationException

请求帮助,Runtime.Serialization.SerializationException

AWS Cognito - SerializationException(在不期望的地方找到结构或映射的开始)

SerializationException:在 c# unity3d 中找不到类型'System.Collections.Generic.List`1

GWT - 偶尔出现 com.google.gwt.user.client.rpc.SerializationException

kotlinx.serialization.SerializationException:找不到类“MultiPartFormDataContent”的序列化程序