XmlSerializer 未将 XML 反序列化为 IEnumerable
XmlSerializer not deserializing XML to IEnumerable
在引用其中一篇 Stack Overflow 帖子 XmlSerializer won't serialize IEnumerable 时,我有以下代码可以正确序列化为 XML,但是当反序列化回来时,IEnumerable 返回为空。
using System.Xml.Linq;
using System.Xml.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
public class Hello{
public static void Main(){
// <!--- Serializing part -->
Glossary glossary1 = new Glossary();
glossary1.Term = "Test1";
glossary1.Definition = "Test1";
Glossary glossary2 = new Glossary();
glossary2.Term = "Test2";
glossary2.Definition = "Test2";
List<Glossary> glossaryList = new List<Glossary>();
glossaryList.Add(glossary1);
glossaryList.Add(glossary2);
GlossaryCollection glossary = new GlossaryCollection(glossaryList);
XDocument doc = new XDocument();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
using (var writer = doc.CreateWriter()) {
xmlSerializer.Serialize(writer, glossary);
}
doc.Save("test.xml");
XDocument doc2 = XDocument.Load("test.xml");
Console.WriteLine(glossary.glossaryList.Count());
Console.WriteLine(doc2.ToString());
//So far looks good - serializing works fine!
// </!--- Serializing part -->
// <!--- De-Serializing part -->
GlossaryCollection temp2;
xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
using (var reader = doc2.Root.CreateReader()) {
var temp = xmlSerializer.Deserialize(reader);
temp2 = (GlossaryCollection) temp;
}
Console.WriteLine(temp2.glossaryList.Count()); // Results in 0, should be 2... :(
// </!--- De-Serializing part -->
}
[XmlRoot]
public class GlossaryCollection {
[XmlIgnore]
public IEnumerable<Glossary> glossaryList;
[XmlElement]
public List<Glossary> GlossarySurrogate { get { return glossaryList.ToList(); } set { glossaryList = value; } } //
public GlossaryCollection() {
glossaryList = new List<Glossary>();
}
public GlossaryCollection(IEnumerable<Glossary> glossaryList) {
this.glossaryList = glossaryList;
}
}
[XmlType("Glossary")]
public class Glossary
{
public string Id { get; set; }
public string Term { get; set; }
public string Definition { get; set; }
}
}
更新:根据 Iridium 的回答,似乎无法将 IEnumerable 与 XmlSerializer 一起使用,因为它每次都返回一个新列表,因此采用了转换为列表的方法。但是,如果有将 glossaryList 保持为 IEnumerable 的解决方案(即使是 hacky),请告诉我 - 即使只是出于纯粹的好奇心。
当您的 XML 序列化类型具有 List<T>
类型的 属性 时,XmlSerializer
将 get
属性 的值,然后调用 .Add(...)
添加反序列化的元素(即它 而不是 set
属性)。
因为 getter 为 GlossarySurrogate
属性 return 每次你 get
都会有一个新列表,XML序列化器使结果丢失。
如果您想让它正常工作,您需要将 glossaryList
字段直接从 GlossarySurrogate
转换为 List<Glossary>
和 return getter,没有调用 .ToList()
。
在引用其中一篇 Stack Overflow 帖子 XmlSerializer won't serialize IEnumerable 时,我有以下代码可以正确序列化为 XML,但是当反序列化回来时,IEnumerable 返回为空。
using System.Xml.Linq;
using System.Xml.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
public class Hello{
public static void Main(){
// <!--- Serializing part -->
Glossary glossary1 = new Glossary();
glossary1.Term = "Test1";
glossary1.Definition = "Test1";
Glossary glossary2 = new Glossary();
glossary2.Term = "Test2";
glossary2.Definition = "Test2";
List<Glossary> glossaryList = new List<Glossary>();
glossaryList.Add(glossary1);
glossaryList.Add(glossary2);
GlossaryCollection glossary = new GlossaryCollection(glossaryList);
XDocument doc = new XDocument();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
using (var writer = doc.CreateWriter()) {
xmlSerializer.Serialize(writer, glossary);
}
doc.Save("test.xml");
XDocument doc2 = XDocument.Load("test.xml");
Console.WriteLine(glossary.glossaryList.Count());
Console.WriteLine(doc2.ToString());
//So far looks good - serializing works fine!
// </!--- Serializing part -->
// <!--- De-Serializing part -->
GlossaryCollection temp2;
xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
using (var reader = doc2.Root.CreateReader()) {
var temp = xmlSerializer.Deserialize(reader);
temp2 = (GlossaryCollection) temp;
}
Console.WriteLine(temp2.glossaryList.Count()); // Results in 0, should be 2... :(
// </!--- De-Serializing part -->
}
[XmlRoot]
public class GlossaryCollection {
[XmlIgnore]
public IEnumerable<Glossary> glossaryList;
[XmlElement]
public List<Glossary> GlossarySurrogate { get { return glossaryList.ToList(); } set { glossaryList = value; } } //
public GlossaryCollection() {
glossaryList = new List<Glossary>();
}
public GlossaryCollection(IEnumerable<Glossary> glossaryList) {
this.glossaryList = glossaryList;
}
}
[XmlType("Glossary")]
public class Glossary
{
public string Id { get; set; }
public string Term { get; set; }
public string Definition { get; set; }
}
}
更新:根据 Iridium 的回答,似乎无法将 IEnumerable 与 XmlSerializer 一起使用,因为它每次都返回一个新列表,因此采用了转换为列表的方法。但是,如果有将 glossaryList 保持为 IEnumerable 的解决方案(即使是 hacky),请告诉我 - 即使只是出于纯粹的好奇心。
当您的 XML 序列化类型具有 List<T>
类型的 属性 时,XmlSerializer
将 get
属性 的值,然后调用 .Add(...)
添加反序列化的元素(即它 而不是 set
属性)。
因为 getter 为 GlossarySurrogate
属性 return 每次你 get
都会有一个新列表,XML序列化器使结果丢失。
如果您想让它正常工作,您需要将 glossaryList
字段直接从 GlossarySurrogate
转换为 List<Glossary>
和 return getter,没有调用 .ToList()
。