在向类中添加新的可选字段后,此类的以前序列化的实例不再可反序列化。
假设我使用BinaryFormatter保存了一些MyClass实例:
[Serializable]
public class MyClass
{
public MyType A;
}
之后,MyClass的第二次修订:
[Serializable]
public class MyClass
{
public MyType A;
[OptionalField(VersionAdded = 2)]
public MyType NewField;
}
现在旧的对象不再可反序列化。我在尝试反序列化时获得的堆栈跟踪如下(配置文件是.NET 4.0):
System.ArgumentNullException: Value cannot be null.
Parameter name: type
at System.Reflection.Assembly.GetAssembly(Type type)
at System.Runtime.Serialization.Formatters.Binary.BinaryConverter.GetParserBinaryTypeInfo(Type type, Object& typeInformation)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, Type objectType, String[] memberNames, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMap(BinaryObjectWithMap record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck)
我无法在互联网或类似的堆栈跟踪上找到此堆栈跟踪。请注意,使用Mono运行软件时可以读取相同的文件;-)。因此,我认为问题可能与.NET错误有关。
答案 0 :(得分:0)
假设我有以下类类型。
[Serializable]
public class MyClass
{
public MyType A;
}
[Serializable]
public class MyType
{
public string Name { get; set; }
}
让我们将MyClass的一个实例序列化为一个文件。
using (var stream = new FileStream(@"c:\temp\test.dat", FileMode.Create, FileAccess.Write))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, new MyClass { A = new MyType { Name = "Christophe" } });
}
现在我们将它反序列化为MyClass的一个实例。
using (var stream = new FileStream(@"c:\temp\test.dat", FileMode.Open, FileAccess.Read))
{
var formatter = new BinaryFormatter();
var myInstance = (MyClass) formatter.Deserialize(stream);
}
没问题。一切正常。让我们在MyClass类型中添加一个新字段。我建议你改用属性。
[Serializable]
public class MyClass
{
public MyType A;
[OptionalField]
public MyType B;
}
反序列化仍然可以正常工作。在我的例子中,B的缺失数据被忽略,并且它被设置为null。