Public fields/properties of a class derived from B

2020-02-02 00:54发布

I'm trying to serialize a class that derives from BindingList(Floor), where Floor is a simple class that only contains a property Floor.Height

Here's a simplified version of my class

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

I'll serialize an instance of CustomBindingList using the following code.

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();

Yet testString above ends getting set to the following 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>"

How do I get "publicField" or "publicProperty to serialize as well?

3条回答
做自己的国王
2楼-- · 2020-02-02 01:29

The short answer here is that .NET generally expects something to be a collection xor to have properties. This manifests in a couple of places:

  • xml serialization; properties of collections aren't serialized
  • data-binding; you can't data-bind to properties on collections, as it implicitly takes you to the first item instead

In the case of xml serialization, it makes sense if you consider that it might just be a SomeType[] at the client... where would the extra data go?

The common solution is to encapsulate a collection - i.e. rather than

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

Normally I wouldn't have a set on a collection property, but XmlSerializer demands it...

查看更多
【Aperson】
3楼-- · 2020-02-02 01:40

XML serialization handles collections in a specific way, and never serializes the fields or properties of the collection, only the items.

You could either :

  • implement IXmlSerializable to generate and parse the XML yourself (but it's a lot of work)
  • wrap your BindingList in another class, in which you declare your custom fields (as suggested by speps)
查看更多
贪生不怕死
4楼-- · 2020-02-02 01:41

This is known issue with XML serialization and inheriting from collections.

You can read more info on this here : http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/0d94c4f8-767a-4d0f-8c95-f4797cd0ab8e

You could try something like this :

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

This means you can add floors by using Floors.Add and you will get the result you want, I hope, however, I didn't try it. Keep in mind that playing around with attributes is the key to XML serialization.

查看更多
登录 后发表回答