序列化列表导出为ICollection<>到XML [英] Serializing a List<> exported as an ICollection<> to XML

查看:81
本文介绍了序列化列表导出为ICollection<>到XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#.NET 3.5应用程序,我想将包含 List<> 的类序列化为XML。我的班级看起来像这样:

I have a C# .NET 3.5 application where I would like to serialize a class containing a List<> to XML. My class looks like this:

[XmlRoot("Foo")]
class Foo
{
    private List<Bar> bar_ = new List<Bar>();

    private string something_ = "My String";

    [XmlElement("Something")]
    public string Something { get { return something_; } }

    [XmlElement("Bar")]
    public ICollection<Bar> Bars
    {
        get { return bar_; }
    }
}

如果我这样填充:

Bar b1 = new Bar();
// populate b1 with interesting data
Bar b2 = new Bar();
// populate b2 with interesting data

Foo f = new Foo();
f.Bars.Add(b1);
f.Bars.Add(b2);

然后像这样序列化它:

using (System.IO.TextWriter textWriter = new System.IO.StreamWriter(@"C:\foo.xml"))
{
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo));
    serializer.Serialize(textWriter, f);
}

我得到的文件看起来像这样:

I get a file that looks like this:

<Foo>
    <Something>My String</Something>
</Foo>

但是,我想要的是看起来像这样的XML:

But, what I want is XML that looks like this:

<Foo>
    <Something>My String</Something>
    <Bar>
        <!-- Data from first Bar -->
    </Bar>
    <Bar>
        <!-- Data from second Bar -->
    </Bar>
</Foo>

我需要怎么做才能获得 List<> 出现在XML中?

What do I need to do to get the List<> to appear in the XML?

推荐答案

XmlSerializer 要求可序列化属性具有setter。除此之外, XmlSerializer 不能序列化接口属性。以下代码将起作用:

The XmlSerializer requires that serializable properties have a setter. Besides that, the XmlSerializer can not serialize interface properties. The following code will work:

[XmlElement("Bar")]
public List<Bar> Bars
{
    get { return bar_; }
    set { throw new NotSupportedException("This property 'Bars' cannot be set. This property is readonly."); }
}

如果您不喜欢这种解决方案(例外情况有点难看)那么您可以实现 IXmlSerializable 并编写自己的自定义序列化。

If you don't like this solution (the exception is kinda ugly) then you could implement IXmlSerializable and write your own custom serialization.

编辑: Artur Mustafin是正确的,实现 IEnumerable 或<$ c的成员$ c> ICollection 不需要设置器,如此msdn页

Artur Mustafin is right, members that implement IEnumerable or ICollection don't need a setter, as is explained on this msdn page:


XmlSerializer对实现 IEnumerable ICollection 的类给予特殊待遇。实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法。 Add方法的参数必须与 GetEnumerator 返回的值的 Current 属性返回的类型相同,或该类型的基础之一。除了 IEnumerable 之外,实现 ICollection (例如CollectionBase)的类还必须具有公共的 Item 带有整数的索引属性(C#中的索引器),并且必须具有整数类型的公共 Count 属性。 Add 方法的参数必须与 Item 属性返回的类型相同,或者是该类型的其中一个基地。对于实现 ICollection 的类,要序列化的值是从索引的 Item 属性中检索的,而不是通过调用 GetEnumerator

The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type's bases. A class that implements ICollection (such as CollectionBase) in addition to IEnumerable must have a public Item indexed property (indexer in C#) that takes an integer, and it must have a public Count property of type integer. The parameter to the Add method must be the same type as is returned from the Item property, or one of that type's bases. For classes that implement ICollection, values to be serialized are retrieved from the indexed Item property, not by calling GetEnumerator.

这篇关于序列化列表导出为ICollection&lt;&gt;到XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆