Problem deserializing a subclass whose base class has a struct that has a reference type

A

Andrew G. J. Fung

Can anyone please explain to me why the code below throws an exception?
It seems to occur when deserializing an instance of a subclass, whose
base class holds a struct, where said struct holds an instance to a
reference type (but not System.String).

The commented out code are lines that when enabled (and any conflicting
lines disabled) stop the exception from being thrown.

Thanks kindly,
Andrew.

---

using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

public class test
{
public static void Main()
{
//Base top = new Base();
Child top = new Child();
top .myStruct_m = new MyStruct();
top.myStruct_m.someValue = new myclass();
//top.myStruct_m.someValue = "foobar";

BinaryFormatter f = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
f.Serialize(ms, top);
ms.Seek(0, SeekOrigin.Begin);
f.Deserialize(ms);
}
}
}

[Serializable]
public sealed class myclass
{}

[Serializable]
public class Base
{
public MyStruct myStruct_m;
}

[Serializable]
public class Child : Base//, ISerializable {
public Child(){}

public Child(SerializationInfo si, StreamingContext sc)
{
myStruct_m = (MyStruct) si.GetValue("foo", typeof(MyStruct));
}

public void GetObjectData(SerializationInfo si, StreamingContext sc)
{
si.AddValue("foo", myStruct_m);
}
}

[Serializable]
public struct MyStruct
{
public object someValue;
}
 
B

Ben Dewey

The exception you are getting is because Child is not serializable. you
need to take out the comments on ISerializable from the Child class.
 
A

Andrew G. J. Fung

Hi, Ben,

Sorry, the code I posted incorrectly had the brace on the same line as
the class declaration for the child class; thus it won't compile "as
is", when I intended it to.

However, I believe the child class *is* serializable, because it is
marked with the SerializableAttribute; implementing ISerializable is
not necessary for a class to be considered serializable. The
interesting thing there is that implementing my own custom
serialization scheme by implementing the ISerializable interface
causes the problem to go away, while achieving the desired result
(serialize and deserialize).

Similarly, if we store a System.String in the struct, there is no
exception. Or if we serialize/deserialize an instance of the base
class rather than the subclass, even though the subclass doesn't
define any new characteristics.

Thanks!
Andrew.

Ben Dewey said:
The exception you are getting is because Child is not serializable. you
need to take out the comments on ISerializable from the Child class.


Andrew G. J. Fung said:
Can anyone please explain to me why the code below throws an exception?
It seems to occur when deserializing an instance of a subclass, whose
base class holds a struct, where said struct holds an instance to a
reference type (but not System.String).

The commented out code are lines that when enabled (and any conflicting
lines disabled) stop the exception from being thrown.

Thanks kindly,
Andrew.

---

using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

public class test
{
public static void Main()
{
//Base top = new Base();
Child top = new Child();
top .myStruct_m = new MyStruct();
top.myStruct_m.someValue = new myclass();
//top.myStruct_m.someValue = "foobar";

BinaryFormatter f = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
f.Serialize(ms, top);
ms.Seek(0, SeekOrigin.Begin);
f.Deserialize(ms);
}
}
}

[Serializable]
public sealed class myclass
{}

[Serializable]
public class Base
{
public MyStruct myStruct_m;
}

[Serializable]
public class Child : Base//, ISerializable {
public Child(){}

public Child(SerializationInfo si, StreamingContext sc)
{
myStruct_m = (MyStruct) si.GetValue("foo", typeof(MyStruct));
}

public void GetObjectData(SerializationInfo si, StreamingContext sc)
{
si.AddValue("foo", myStruct_m);
}
}

[Serializable]
public struct MyStruct
{
public object someValue;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top