【发布时间】:2015-11-21 02:44:23
【问题描述】:
我已经阅读了很多其他关于 c# xml 序列化的问题,但我似乎无法解决我遇到的这个小小的理解问题。
我希望它不会太长,请考虑以下代码:
public class Grandparent {
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
public class ParentA : Grandparent {
private Grandparent _neighbor;
[XmlAttribute(AttributeName = "neighbor")]
public string NeighborName { get { return _neighbor.Name; } }
public ParentA() : this(null) { }
public ParentA(Grandparent neighbor) {
setNeighbor(neighbor);
}
public void setNeighbor(Grandparent neighbor) {
// Do some checking
_neighbor = neighbor;
}
}
public class ParentB : Grandparent {
private List<Grandparent> _people;
[XmlElement(ElementName = "child1")]
public List<ChildA1> Children1 { get { return _people.Where(p => p.GetType() == typeof(ChildA1)).Cast<ChildA1>().ToList(); } }
[XmlElement(ElementName = "child2")]
public List<ChildA2> Children2 { get { return _people.Where(p => p.GetType() == typeof(ChildA2)).Cast<ChildA2>().ToList(); } }
[XmlElement(ElementName = "parentc")]
public List<ParentC> ParentsC { get { return _people.Where(p => p.GetType() == typeof(ParentC)).Cast<ParentC>().ToList(); } }
public ParentB() {
_people = new List<Grandparent>();
}
public void AddPerson(Grandparent person) {
// Do some checking
_people.Add(person);
}
}
public class ParentC : Grandparent {
}
public class ChildA1 : ParentA {
}
public class ChildA2 : ParentA {
}
[XmlRoot("myroot")]
public class Model {
private List<ParentB> _parents;
[XmlElement(ElementName = "parentb")]
public List<ParentB> Parents { get { return _parents; } }
public Model() {
_parents = new List<ParentB>();
}
public void AddParent(ParentB parent) {
// Do some checking
_parents.Add(parent);
}
public string Serialize() {
XmlSerializer serializer = new XmlSerializer(typeof(Model));
using (StringWriter writer = new StringWriter()) {
serializer.Serialize(writer, this);
return writer.ToString();
}
}
}
现在让我们创建一个模型并用一些数据填充它:
Model model = new Model();
ChildA1 child1 = new ChildA1 { Name = "Alex" };
ChildA1 child2 = new ChildA1 { Name = "Ben" };
ChildA2 child3 = new ChildA2 { Name = "Jim" };
ChildA2 child4 = new ChildA2 { Name = "Pete" };
child1.setNeighbor(child2);
child2.setNeighbor(child1);
child3.setNeighbor(child4);
child4.setNeighbor(child3);
ParentB parent1 = new ParentB { Name = "Fred" };
ParentC parent2 = new ParentC { Name = "Sam" };
parent1.AddPerson(parent2);
parent1.AddPerson(child1);
parent1.AddPerson(child2);
parent1.AddPerson(child3);
parent1.AddPerson(child4);
model.AddParent(parent1);
textBox1.Text = model.Serialize();
这是我们得到的输出xml:
<?xml version="1.0" encoding="utf-16"?>
<myroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<parentb name="Fred">
<child1 name="Alex" />
<child1 name="Ben" />
<child2 name="Jim" />
<child2 name="Pete" />
<parentc name="Sam" />
</parentb>
</myroot>
现在我们终于找到了我的问题的原因:
据我了解,只有公共数据会被序列化,这意味着方法(或从它们返回的数据)不会被序列化。
所以像public string Test { get; set; } 这样的东西可能会转化为一个公共领域......所以它可能会被序列化。
但是这个呢:public string Test { get { return _someString; } }?
这只是像public string get_Test() { return _someString; } 这样的普通方法的语法糖,不是吗?而且我们知道从方法返回的数据没有被序列化,对吗?
是的,有证据:
[XmlAttribute(AttributeName = "neighbor")]
public string NeighborName { get { return _neighbor.Name; } }
这没有被序列化。 但是等等..什么?以下一项有效:
[XmlElement(ElementName = "child1")]
public List<ChildA1> Children1 { get { return _people.Where(p => p.GetType() == typeof(ChildA1)).Cast<ChildA1>().ToList(); } }
我想我可以争辩说,像public string Test { get { return _someObj.someString; } } 这样的简单getter 只是访问一个数据字段,可能 转换为可以序列化的东西?但是上面发布的更复杂的 getter 确实有效,为什么简单版本(邻居)不起作用?
我一定是错过了什么……它盯着我的眼睛,但我就是看不见。
请帮我解开这个谜题。
PS:上面的类和代码只是对实际引发此问题的代码的重新构建。它的结构相似,产生的输出也非常相似。我确实很快在应用程序中实现和测试了这段代码,它似乎表明了我的问题,如果我在克隆原始代码的基本结构时犯了一些错误,请原谅我。
【问题讨论】:
-
是否打算将一个用
XmlAttribute装饰,另一个用XmlElement装饰?
标签: c# xml serialization