Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid output with inherit class

I have 2 classes

[DataContract, KnownType(typeof(B))]
public class A
{
    [DataMember]
    public string prop1 { get; set; }
    [DataMember]
    public string prop2 { get; set; }
    [DataMember]
    public string prop3 { get; set; }
}

[DataContract]
public class B : A
{
    [DataMember]
    public string prop4 { get; set; }
}

and the following method:

List<B> BList = new List<B>();
BList = new List<B>() { new B() { prop1 = "1", prop2 = "2", prop3 = "3", prop4 = "4" } };
List<A> AList = BList.Cast<A>().ToList();
DataContractSerializer ser = new DataContractSerializer(typeof(List<A>));
FileStream fs = new FileStream(@"C:\temp\AResult.xml", FileMode.Create);
using (fs)
{
    ser.WriteObject(fs, AList);
}

which writes this to the outcoming XML file:

<ArrayOfProgram.A xmlns="http://schemas.datacontract.org/2004/07/foo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Program.A i:type="Program.B">
<prop1>1</prop1>
<prop2>2</prop2>
<prop3>3</prop3>
<prop4>4</prop4>
</Program.A></ArrayOfProgram.A>

How could it happen, that prop4 is within the result and how can I avoid this? prop4 is not part of List<A> which is being serialized.

like image 225
c0rd Avatar asked Sep 21 '16 10:09

c0rd


1 Answers

That happens because you are storing in AList the pointer to the B object instance. When you did "new B() { prop1 = "1", prop2 = "2", prop3 = "3", prop4 = "4" }" you created an B object instance. When the serializer reflects the object stored in AList, it finds an actual B object instance, because you didint change the B object instance, you only stored it in the AList. The compiler allowed you to do that because the inheritance chain permits it but the B object instance was not changed, then it is a B object instance no matters where you store it.

Instead of doing:

List<A> AList = BList.Cast<A>().ToList();

Do:

List<A> AList = BList.Select(b => new A() 
{ prop1 = b.prop1, prop2 = b.prop2, prop3 = b.prop3 })
.ToList();

That will create a new A instance for each B instance in BList

like image 149
Santiago Regojo Avatar answered Sep 29 '22 15:09

Santiago Regojo