从BindingList <t>派生的类的公共字段/属性不会序列化</t>

时间:2009-08-04 04:36:42

标签: c# serialization xml-serialization bindinglist

我正在尝试序列化一个派生自 BindingList(Floor)的类,其中 Floor 是一个只包含属性 Floor.Height的简单类

这是我班级的简化版本

[Serializable]
[XmlRoot(ElementName = "CustomBindingList")]
public class CustomBindingList:BindingList<Floor>
{
    [XmlAttribute("publicField")]
    public string publicField;
    private string privateField;

    [XmlAttribute("PublicProperty")]
    public string PublicProperty
    {
        get { return privateField; }
        set { privateField = value; }
    }
}

我将使用以下代码序列化CustomBindingList的实例。

XmlSerializer ser = new XmlSerializer(typeof(CustomBindingList));
StringWriter sw = new StringWriter();

CustomBindingList cLIst = new CustomBindingList();

Floor fl;

fl = new Floor();
fl.Height = 10;
cLIst.Add(fl);

fl = new Floor();
fl.Height = 10;    
cLIst.Add(fl);

fl = new Floor();
fl.Height = 10;
cLIst.Add(fl);

ser.Serialize(sw, cLIst);

string testString = sw.ToString();

上面的 testString 结尾设置为以下XML:

<CustomBindingList xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
    <Floor Height="10" />
    <Floor Height="10" />
    <Floor Height="10" />
</CustomBindingList>"

如何将“publicField”或“publicProperty序列化?”

3 个答案:

答案 0 :(得分:3)

这里简短的回答是,.NET通常希望 集合 xor 具有属性。这体现在以下几个方面:

  • xml序列化;集合的属性未序列化
  • 数据绑定;您无法将数据绑定到集合上的属性,因为它隐式地将您带到第一个项目

在xml序列化的情况下,如果您认为它可能只是客户端的SomeType[]那么有意义......额外的数据会去哪里?

常见的解决方案是封装集合 - 即而不是

public class MyType : List<MyItemType> // or BindingList<...>
{
    public string Name {get;set;}
}

public class MyType
{
    public string Name {get;set;}
    public List<MyItemType> Items {get;set;} // or BindingList<...>
}

通常我在集合属性上没有set,但XmlSerializer要求它...

答案 1 :(得分:2)

XML序列化以特定方式处理集合,从不序列化集合的字段或属性,只序列化项目。

你可以:

  • 实现IXmlSerializable自己生成和解析XML(但这是很多工作)
  • 将BindingList包装在另一个类中,您可以在其中声明自定义字段(由speps建议)

答案 2 :(得分:1)

这是XML序列化和从集合继承的已知问题。

您可以在此处阅读有关此内容的更多信息:http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/0d94c4f8-767a-4d0f-8c95-f4797cd0ab8e

您可以尝试这样的事情:

[Serializable]
[XmlRoot]
public class CustomBindingList
{
    [XmlAttribute]
    public string publicField;
    private string privateField;

    [XmlAttribute]
    public string PublicProperty
    {
        get { return privateField; }
        set { privateField = value; }
    }

    [XmlElement]
    public BindingList<Floor> Floors = new BindingList<Floor>();
}

这意味着你可以使用Floors.Add添加楼层,你会得到你想要的结果,我希望,但是,我没有尝试过。请记住,使用属性是XML序列化的关键。