2012-06-05 3 views
1

클래스에 새 선택적 필드를 추가 한 후에이 클래스의 이전에 serialize 된 인스턴스는 더 이상 deserializable이 불가능합니다.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됩니다. 내가 인터넷 또는 유사한 스택 추적에이 스택 트레이스를 찾을 수 없습니다

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) 

:를 역 직렬화 할 때 내가 얻을 스택 추적은 다음 (프로파일은 .NET 4.0)입니다. 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에 대한 누락 된 데이터가 무시되고 null로 설정됩니다.

+0

고마워요, 당신이 묘사하는 상황이 제 경우예요.하지만 제 경우에는 오류가 있습니다. MyClass는 semplification이며, 실제 클래스에는 많은 필드와 새로운 선택적 필드가 있습니다. 그 문제는 속성 사용과 관련이 없으며 OptionalField 속성으로 표시 할 수 없다고 생각합니다. Microsoft 버그를 어디에서 게시 할 수 있습니까? – matteot

+0

버그가 아닌 것으로 의심됩니다. 정확히이 MyType입니까? –

+0

.NET serialization이 BUGGY입니다! 직렬화에 대한 이해할 수없는 문제가 발생한 첫 번째 (또는 두 번째) 시간이 아닙니다. 작동하지 않아도되는 작업. [직렬화되지 않은] 또한 작동하지 않습니다. – user20493

관련 문제