我有一组具有以下结构的类:计划>元素>列表与LT;组件>
[Serializable, XmlRoot("Plan")]
public class Plan
{
public Plan()
{
elements = new Elements();
}
public int floor {get; set};
[XmlElement("elements")]
public Elements elements { get; set; }
}
[Serializable, XmlType("elements")]
public class Elements
{
public Elements() { Items = new List<Element>(); }
[XmlElement("element")]
public List<Element> Items { get; set; }
}
[Serializable]
public class Element
{
public int id { get; set; }
}
所有这些都使用System.Xml.Serialization序列化到这个XML:
<?xml version="1.0"?>
<Plan xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<elements>
<element>
<id>0</id>
</element>
</elements>
</Plan>
但是当我尝试再次反序列化时,Elements类根本没有填充,并且在Serialize-&gt; Deserialize-&gt; Serialize过程之后的结果如下所示:
<?xml version="1.0"?>
<Plan xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<floor>0</floor>
<elements />
</Plan>
这是我的反序列化功能:
public class Program {
public Plan plan;
public static void deserializeXml<T>(this T toDeserialize, string filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize.GetType());
Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
toDeserialize = (T) xmlSerializer.Deserialize(stream);
}
public void loadXml() {
deserializeXml(plan, "plan.xml");
}
}
有人能给我一个线索,为什么这不起作用?谢谢!
答案 0 :(得分:0)
我让你的代码使用与序列化本身无关的微小修改,因此问题似乎不是xml序列化本身,而是它的调用方式:
public static void deserializeXml<T>(this T toDeserialize, string filename)
{
// !!!! toDeserialize is a copy to instance in the heap, so -> ...
XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize.GetType());
Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
// -> ... here we assign reference of deserialized instance to toDeserialize(which is a copy)
toDeserialize = (T) xmlSerializer.Deserialize(stream);
// we need to return result here, otherwise this reference copy will be left dying here
}
代码:
static class Serializer
{
// note here: deserializeXml returns reference to deserialized instance
public static T deserializeXml<T>(string filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var toDeserialize = (T)xmlSerializer.Deserialize(stream);
return toDeserialize;
}
}
public static void serializeToXml<T>(T instance, string filename)
{
var xmlSerializer = new XmlSerializer(instance.GetType());
using (Stream stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
{
xmlSerializer.Serialize(stream, instance);
}
}
}
所以以下列方式运行它:
Plan p = new Plan();
p.elements.Items.Add(new Element { id = 1 });
p.elements.Items.Add(new Element { id = 2 });
p.elements.Items.Add(new Element { id = 3 });
Serializer.serializeToXml(p, @"D:\1.xml");
var p2 = Serializer.deserializeXml<Plan>(@"D:\1.xml");
Console.WriteLine(p2.elements.Items.Count);
Serializer.serializeToXml(p2, @"D:\2.xml");
最后会给出相同的D:\1.xml
和D:\2.xml
。
希望这有帮助