|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Custom Formatter - ValueType ISerializable Deserialization Problemclass, but I can't persuade fixups to work properly with structs. What am I doing wrong? The first call to Test() works as expected: c.s.o ends up as a boxed integer. The second call doesn't work: c.s.o is left as null rather than as the expected boxed integer. The only difference between the two calls is that the first one is emulating using reflection to deserialize the class (C1) and the second call is using custom serialization (via ISerializable) to emulate deserializing the class. This code is a self-contained, cut down version that demonstrates the problem I'm having. I want to know why the SerializationInfo object that is passed to the C2 constructor hasn't been fixed-up with the fixup recorded in the om.RecordFixup(2, so_mi, 4) call. [Class1.cs] using System; using System.Reflection; using System.Runtime.Serialization; namespace Test { class Class1 { static MemberInfo so_mi = typeof(S).GetMember("o")[0]; static void Main() { object c; c = Test(typeof(C1), null); // c.s.o == {4} SerializationInfo info = new SerializationInfo(c.GetType(), new FormatterConverter()); info.AddValue("s", new S()); c = Test(typeof(C2), info); // c.s.o != {4} } static S s; static object Test(Type type, SerializationInfo info) { ObjectManager om = new ObjectManager(null, new StreamingContext(StreamingContextStates.All, null)); object c = FormatterServices.GetUninitializedObject(type); om.RegisterObject(c, 1, info); MemberInfo m = type.GetField("s"); om.RegisterObject(new S(), 2, null, 1, m); om.RecordFixup(2, so_mi, 4); om.RegisterObject((object)4, 4); om.DoFixups(); return om.GetObject(1); } } class C1 { public S s; } class C2 : ISerializable { public S s; C2(SerializationInfo info, StreamingContext context) { s = (S)info.GetValue("s", typeof(S)); } public void GetObjectData(SerializationInfo info, StreamingContext context) { } } struct S { public object o; } } [attached file: Class1.cs] The line
SerializationInfo info = new SerializationInfo(c.GetType(), new FormatterConverter()); should have been SerializationInfo info = new SerializationInfo(typeof(C2), new FormatterConverter()); And I think I've worked out what I'm doing wrong: if I also register the value type as a delayed fixup then the code appears to work. static object Test(Type type, SerializationInfo info) { ObjectManager om = new ObjectManager(null, new StreamingContext(StreamingContextStates.All, null)); object c = FormatterServices.GetUninitializedObject(type); om.RegisterObject(c, 1, info); if (info != null) om.RecordDelayedFixup(1, "s", 2); om.RegisterObject(new S(), 2, null, 1, null); om.RecordFixup(2, s.GetType().GetField("o"), 4); om.RegisterObject((object)4, 4); om.DoFixups(); return om.GetObject(1); } |
|||||||||||||||||||||||