Question

I have a class with a list of objects that is serialized and deserialized:

[DataContract]
public class Manager
{
  [DataMember]
  public BigBase[] enemies;
}

The class with subclasses:

[DataContract]
[KnownType(typeof(Medium))]
[KnownType(typeof(Small))]
public class BigBase
{
    [DataMember]
    public bool isMoving;
}
[DataContract]
public class Medium : BigBase
{
}
[DataContract]
public class Small: BigBase
{
}

Now whats strange when deserializing the enemies array will contain correctly deserialized BigBase classes but each Medium and Small class doesnt have the correct value for isMoving.

Was it helpful?

Solution

You need to put KnownType attribute on Manager:

[DataContract]
[KnownType(typeof(Medium))]
[KnownType(typeof(Small))]
public class Manager
{
  [DataMember]
  public BigBase[] enemies;
}

Because it's the Manager which has an array of BigBase whose elements might be the derived classes as well. So the DataContractSerializer will know what to expect from the array when serializing and deserializing Manager object (and it's all DataMember).

OTHER TIPS

[DataContract]
public class Medium : BigBase
{
    [DataMember]
    public string UpgradedName;
}

I dont see that in this test Code. I think your serialization code is wrong.

Sample calls:

Manager test = new Manager();

            Medium medium = new Medium() {isMoving = true,Name = "medium", UpgradedName = "mediaum name"};
            //some items in array
            test.enemies = new BigBase[] {medium,new Small{isMoving = false},new Small{isMoving = true}, new BigBase {Name = "bigbase", isMoving = true}, new BigBase {Name = "bigbase2", isMoving = true}, new BigBase {Name = "bigbase3", isMoving = true}} ;

            DataContractSerializer serializer = new DataContractSerializer(typeof (Manager));
            FileStream writer = new FileStream("test123.txt", FileMode.Create);
            serializer.WriteObject(writer, test);
            writer.Close();
            writer = new FileStream("test123.txt", FileMode.Open);
            Manager deserializedmanager = serializer.ReadObject(writer) as Manager;
            //verify serialized object
            Console.WriteLine("medium object:"+ (deserializedmanager.enemies[0]  as Medium).UpgradedName);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top