2012-06-05 51 views
1

在向类添加新的可选字段之后,此类的先前序列化的实例不再可反序列化。使用OptionalField的反序列化错误

假设我有救使用BinaryFormatter的MyClass的一些实例:

[Serializable] 
public class MyClass 
{ 
    public MyType A; 
} 

后,MyClass的第二次修改:

[Serializable] 
public class MyClass 
{ 
    public MyType A; 

    [OptionalField(VersionAdded = 2)] 
    public MyType NewField; 
} 

现在年纪大物体不再deserializable。堆栈跟踪我尝试反序列化时,他们得到的是以下(配置文件是.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

VersionAdded属性在.NET 4上标记为保留,尝试在没有它的情况下运行代码。 –

回答

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的缺失数据将被忽略,并将其设置为空。

+0

谢谢,你描述的情况正是我的情况,但在我的情况下,我有一个错误。 MyClass是一个semplification,我真正的类有很多字段和一个新的可选字段。我认为这个问题与使用属性无关(并且不能用属性OptionalField来标记) 你知道在哪里发布微软的bug吗? – matteot

+0

我怀疑这是一个bug。你可以发表你如何反序列化和什么正确的是MyType? –

+0

我也有这个问题!.NET序列化是BUGGY!这不是第一次(也不是第二次)我有序列化难以理解的问题。应该工作的事情,不要。[非序列化]也没有工作 – user20493