我有两节课

[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; }
}

以及以下方法:
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);
}

它将此写入输出的XML文件:
<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>

怎么可能,结果中有prop4,我如何避免?prop4不是正在序列化的List<A>的一部分。

最佳答案

这是因为您在alist中存储了指向b对象实例的指针。当您执行“new b(){prop1=”1“,prop2=”2“,prop3=”3”,prop4=”4“}”时,您创建了一个b对象实例。
当序列化程序反映存储在alist中的对象时,它会找到一个实际的b对象实例,因为您没有更改b对象实例,所以只将其存储在alist中。编译器允许您这样做,因为继承链允许它,但b对象实例没有更改,那么它就是b对象实例,不管您将它存储在哪里。
而不是:

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

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

它将为blist中的每个b实例创建一个新的a实例

09-16 15:31