SerializationException:找不到类型';系统.集合.通用.c#unity3d中的列表'1
我试图在c#unity3d中序列化和反序列化一个对象。为此,我使用下面的代码。但是我得到了下面提到的一个错误 错误:序列化异常:找不到类型“System.Collections.Generic.List`1[[ABC,Assembly CSharp,Version=1.0.2.18931,Culture=neutral,PublicKeyToken=null]]” 当我在玩游戏时序列化对象保存到文件并从文件中加载它而不停止游戏时,不会发生这种情况 但是,如果我停止游戏并更改任何代码行(与序列化和反序列化无关),并从先前保存的文件加载数据并尝试反序列化,则会发生错误。我将获得一个SerializationException:找不到类型';系统.集合.通用.c#unity3d中的列表'1,c#,.net,generics,unity3d,serialization,C#,.net,Generics,Unity3d,Serialization,我试图在c#unity3d中序列化和反序列化一个对象。为此,我使用下面的代码。但是我得到了下面提到的一个错误 错误:序列化异常:找不到类型“System.Collections.Generic.List`1[[ABC,Assembly CSharp,Version=1.0.2.18931,Culture=neutral,PublicKeyToken=null]]” 当我在玩游戏时序列化对象保存到文件并从文件中加载它而不停止游戏时,不会发生这种情况 但是,如果我停止游戏并更改任何代码行(与序列化和
序列化异常
我使用的是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();
}
}
但是我得到了同样的异常,并且登录的
BindToType
从未打印过。因此,它意味着SerilizationBinder
中的函数BindToType
二进制格式化程序正在存储程序集版本信息以及序列化类型。因此,即使类型没有更改,序列化/反序列化也会在程序集更新后立即更改
详见本相关Q/A:和
通常情况下,我会将此作为副本关闭投票,但由于公开悬赏,我无法关闭投票,因此我决定回答;) 对于快速二进制序列化来说是一个不错的选择。它还应该解决兼容性问题(您可以手动控制字段顺序/排除)请发布您试图在其上使用的类。另外,请说明您如何调用这些函数以及错误发生的位置。是否有任何方法可以让我私下向您发送文件,因为我使用的是第三方资产,我无法直接将其发布到此处我不要求文件。您尝试序列化/反序列化的类以及如何在此类上使用这两个函数我添加了调用和类结构原因是序列化后的
memStr
和反序列化前的ms
不相同。您能调试并比较memStr
和ms
吗?编辑了问题,试图解决问题,但出现了相同的错误,请查看it@djkp您在哪里使用CurrentAssemblyDeserialization活页夹?bf.Binder=new CurrentAssemblyDeserializationBinder()
不在您更新的代码中。很抱歉,我在更新时出错,添加了它,谢谢:)@djkp我无法用您的实际对象测试它,因为它未完全提供(缺少示例类
,游戏对象
,可序列化字典
,缺少可序列化
,…)但对我来说,BindToType
是为一个小测试类调用的。也许你可以先用一个更简单的类型测试该方法,然后找出复杂类的哪一部分起了作用。这发生在同一个项目中,甚至没有在一个项目中序列化,也没有在另一个项目中反序列化。但协议缓冲区不是使用unityGameObject
数据类型时,您是否使用我提供的呼叫进行了尝试
[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));
}
}