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.

有帮助吗?

解决方案

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).

其他提示

[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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top