2012-06-05 50 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