C# 如何使用XmlInclude序列化IEnumerable
我遇到了使用C# 如何使用XmlInclude序列化IEnumerable,c#,.net,serialization,xml-serialization,ienumerable,C#,.net,Serialization,Xml Serialization,Ienumerable,我遇到了使用XmlSerializer序列化IEnumerable的问题。由于IEnumerable表示对象的列表,因此XmlSerializer无法提前知道需要序列化哪些类型。但因为它需要知道,所以当遇到非对象的类型时,它会抛出一个invalidoOperationException 不应使用Foo.Bar类型。使用XmlInclude或SoapInclude属性指定静态未知的类型 xmlcludeAttribute旨在应用于一种方法,以指示返回值可以是某种类型。但是,IEnumerable没
XmlSerializer
序列化IEnumerable
的问题。由于IEnumerable
表示对象的列表,因此XmlSerializer
无法提前知道需要序列化哪些类型。但因为它需要知道,所以当遇到非对象
的类型时,它会抛出一个invalidoOperationException
不应使用Foo.Bar类型。使用XmlInclude或SoapInclude属性指定静态未知的类型
xmlcludeAttribute
旨在应用于一种方法,以指示返回值可以是某种类型。但是,IEnumerable
没有我可以设置属性的方法
我尝试将它们应用于GetEnumerator
:
public class Bar : IEnumerable
{
private List<object> list;
public Bar()
{
}
[XmlInclude(typeof(Bar))]
[XmlInclude(typeof(ChildBar))]
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
public void Add(Bar bar)
{
list.Add(bar);
}
public void Add(ChildBar childBar)
{
list.Add(childBar);
}
// used for deserialization
public void Add(object o)
{
if (o is Bar || o is ChildBar)
{
list.Add(o);
}
}
// more irrelevant stuff
}
public class ChildBar
{
public ChildBar()
{
}
// more irrelevant stuff
}
公共类栏:IEnumerable
{
私人名单;
公共酒吧()
{
}
[xmlclude(条的类型))]
[xmlclude(typeof(ChildBar))]
公共IEnumerator GetEnumerator()
{
返回list.GetEnumerator();
}
公共空白添加(条形)
{
列表。添加(条);
}
公共无效添加(ChildBar ChildBar)
{
添加(childBar);
}
//用于反序列化
公共无效添加(对象o)
{
如果(o是Bar | | o是ChildBar)
{
列表。添加(o);
}
}
//更不相干的东西
}
公营儿童酒吧
{
公共儿童酒吧()
{
}
//更不相干的东西
}
这并没有解决问题,我也不知道在哪里可以使用这些属性
我应该把它们放在哪里?没有他们我能解决吗?我可以避免编写我自己的枚举器吗?编辑:因为它们与我以前的答案有一些缺陷-没有包含更多条的条,也没有使用xmlAttributes。这是我的新解决方案:但这没有实现
编辑:我回顾了一些事情,这是我通过实现ICollection的最终解决方案,希望这能帮助任何试图找到序列化集合的解决方案的人
public class Program
{
static void Main(string[] args)
{
var program = new Program();
program.SerializeObject();
}
private int tierIndex = 1;
public void SerializeObject()
{
var barCollection = new BarCollection();
var bar1 = new Bar() { Name = "bar1" };
barCollection.Add(bar1);
var bar2 = new Bar() { Name = "bar2" };
barCollection.Add(bar2);
var bar3 = new Bar() { Name = "bar3" };
bar2.BarCollection.Add(bar3);
var bar4 = new Bar() { Name = "bar4" };
bar2.BarCollection.Add(bar4);
var bar5 = new Bar() { Name = "bar 5" };
barCollection.Add(bar5);
var bar6 = new Bar() { Name = "bar 6" };
barCollection.Add(bar6);
var bar7 = new Bar() { Name = "bar 7" };
bar6.BarCollection.Add(bar7);
var bar8 = new Bar() { Name = "bar 8" };
bar7.BarCollection.Add(bar8);
var x = new XmlSerializer(typeof(BarCollection));
x.Serialize(Console.Out, barCollection);
Console.WriteLine("\n");
WriteCollection(barCollection);
Console.ReadLine();
}
public void WriteCollection(BarCollection barCollection)
{
tierIndex++;
foreach (Bar bar in barCollection)
{
Console.Write(new StringBuilder().Insert(0, "--", tierIndex) + "> ");
Console.Write(bar.Name + "\n");
WriteCollection(bar.BarCollection);
}
tierIndex--;
}
}
public class BarCollection : ICollection
{
private readonly ArrayList barNodes = new ArrayList();
public Bar this[int index]
{
get { return (Bar) barNodes[index]; }
}
public void CopyTo(Array a, int index)
{
barNodes.CopyTo(a, index);
}
public int Count
{
get { return barNodes.Count; }
}
public object SyncRoot
{
get { return this; }
}
public bool IsSynchronized
{
get { return false; }
}
public IEnumerator GetEnumerator()
{
return barNodes.GetEnumerator();
}
public void Add(Bar bar)
{
barNodes.Add(bar);
}
public void Add(Object bar)
{
barNodes.Add((Bar) bar);
}
}
public class Bar
{
[XmlAttribute(AttributeName = "Name")]
public string Name;
[XmlArray(ElementName = "BarNodes", IsNullable = true)]
public BarCollection BarCollection = new BarCollection();
}
以下是输出:
<?xml version="1.0" encoding="IBM437"?>
<ArrayOfBar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Bar Name="bar1">
<BarNodes />
</Bar>
<Bar Name="bar2">
<BarNodes>
<Bar Name="bar3">
<BarNodes />
</Bar>
<Bar Name="bar4">
<BarNodes />
</Bar>
</BarNodes>
</Bar>
<Bar Name="bar 5">
<BarNodes />
</Bar>
<Bar Name="bar 6">
<BarNodes>
<Bar Name="bar 7">
<BarNodes>
<Bar Name="bar 8">
<BarNodes />
</Bar>
</BarNodes>
</Bar>
</BarNodes>
</Bar>
</ArrayOfBar>
----> bar1
----> bar2
------> bar3
------> bar4
----> bar 5
----> bar 6
------> bar 7
--------> bar 8
难道IXmlSerializable
不要求您自己编写所有序列化代码吗?那对我来说真的很痛苦。没有更简单的解决方案吗?是的,类型(T)需要实现IXmlSerializable
。使用读写方法,它们实现起来并不难,只需说writer.writeStarElement(“”
和writer.WriteAttribute(“”
等)就可以了。请看一下这一点:是的,不应该说很容易,因为每个类都可能有相当多的信息要写入XML文件。如果要将所有字段写入XML文件,也可以循环遍历类的字段。是否有证据证明XmlSerializer
在WriteXml
方法中工作?MSDN文档让我觉得它没有,因为它提到了序列化文档,而不是元素。你说的文档和元素是什么意思传递给WriteXml方法的XmlWriter编写器是编写元素的编写器。