c# - 反序列化列表
问题描述
我正在将一组应用程序从 .Net Framework 4.7 迁移到 .Net 5.0,但在反序列化方面遇到了一些问题。
下面的示例说明了我面临的问题。如果这两个应用程序都是 .Net 框架,它可以正常工作。如果两者都是.Net 5.0,它工作正常。但是,如果一个应用程序是 .Net 4.7 而另一个是 5.0,则在反序列化 type 时会出现异常List<IList>
。
.Net 5.0 应用程序CreateData:
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Test;
namespace CreateData
{
class Program
{
static void Main()
{
DataStructure dataStructure = new DataStructure();
ArrayList arrayList = new ArrayList();
arrayList.Add(42);
dataStructure.data.Add(arrayList);
// Open a stream for writing
FileStream fs = new FileStream(@"C:\DataFile.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, dataStructure);
fs.Close();
Console.WriteLine("Data file created, press Enter to exit");
Console.ReadLine();
}
}
}
.Net 标准 2.0 库Lib:
using System;
using System.Collections;
using System.Collections.Generic;
namespace Test
{
[Serializable]
public class DataStructure
{
public DataStructure()
{
data = new List<IList>();
}
public List<IList> data;
}
}
.Net 4.7 应用程序ReadData:
using System;
using System.Linq;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Test;
namespace ReadData
{
class Program
{
static void Main()
{
DataStructure dataStructure = new DataStructure();
// Open the data file
FileStream fs = new FileStream(@"C:\DataFile.dat",FileMode.Open);
// Construct the binary formatter
BinaryFormatter bf = new BinaryFormatter();
// deserialize
dataStructure = (DataStructure) bf.Deserialize(fs);
fs.Close();
// Announce success
Console.WriteLine("Value = {0}", dataStructure.data.First()[0]);
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
}
System.Runtime.Serialization.SerializationException:无法加载类型 System.Collections.Generic.List`1 [[System.Collections.IList,System.Private.CoreLib,版本 = 5.0.0.0,文化 = 中性,PublicKeyToken = 7cec85d7bea7798e]]需要反序列化。在 System.Runtime.Serialization.ObjectManager.CompleteObject(ObjectHolder holder, Boolean bObjectFullyComplete) 在 System.Runtime.Serialization.ObjectManager.DoNewlyRegisteredObjectFixups(ObjectHolder holder) 在 System.Runtime.Serialization.ObjectManager.RegisterObject(Object obj, Int64 objectID, SerializationInfo info , Int64 idOfContainingObj, MemberInfo 成员, Int32[] arrayIndex) 在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.RegisterObject(Object obj, ParseRecord pr, ParseRecord objectPr, Boolean bIsString) 在 System.Runtime.Serialization.Formatters.Binary。
在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler , Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter。在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream,HeaderHandler handler) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) 在 ReadData.Program.Main() 中
有没有办法加载类型System.Collections.Generic.List1[[System.Collections.IList, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
?我能做些什么来解决这个问题?
如果可能的话,我想一次迁移一个应用程序,而不是一次性迁移整个代码库。
谢谢!
解决方案
恭喜!您找到了不使用 BinaryFormatter 的原因之一。其他原因包括安全性、性能和尺寸。我建议尽快切换到其他任何东西。
管理序列化的推荐方法是将用于序列化的类型与包含实际逻辑的类型分开。这允许为各自的目的调整各自的类型。向后兼容性之类的事情更简单,因为通常可以添加属性之类的事情,并且您可以选择保留同一类型的多个版本,以防类型结构发生较大的变化。
我还强烈建议设置单元测试,以测试不同类型的序列化/反序列化是否正确。但是单元测试通常也是一个非常有用的工具,可以用来了解序列化库的可能性。
你也许可以做一些类似type-mapping 的事情,但在我看来这是一个巨大的障碍。将类型更改为数组而不是列表也可能会有所帮助,但是如果您要更改序列化格式,则最好切换到更好的格式。可以在 .net 4.7 中编写一个转换器来在旧格式和新格式之间进行转换。