序列化列表导出为ICollection<>到XML [英] Serializing a List<> exported as an ICollection<> to 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
orICollection
. A class that implementsIEnumerable
must implement a publicAdd
method that takes a single parameter. The Add method's parameter must be of the same type as is returned from theCurrent
property on the value returned fromGetEnumerator
, or one of that type's bases. A class that implementsICollection
(such as CollectionBase) in addition toIEnumerable
must have a publicItem
indexed property (indexer in C#) that takes an integer, and it must have a publicCount
property of type integer. The parameter to theAdd
method must be the same type as is returned from theItem
property, or one of that type's bases. For classes that implementICollection
, values to be serialized are retrieved from the indexedItem
property, not by callingGetEnumerator
.
这篇关于序列化列表导出为ICollection<>到XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!