嵌套类成员序列化

时间:2017-04-05 06:47:40

标签: c# serialization

我正在尝试找出序列化嵌套类的最佳方法,而不必序列化整个嵌套类成员。假设以下类:

public class ClassA
{
  public decimal ID { get; set; }
}

public class ClassA1 : ClassA
{
  public decimal Name { get; set; }
  public decimal Value { get; set; }
  public decimal Description { get; set; }
}

public class ClassA2 : ClassA
{
  public ClassA1 Details { get; set; }
  public int SomeValue { get; set; }
}

我有一个ClassA1类型的固定对象列表,它们存储在List类型的变量中。

我还有一个ClassA2类型的对象列表,它们存储在List

类型的变量中

我想要做的是序列化和反序列化我的ClassA2对象列表。自动序列化将序列化每个ClassA1对象的整个内容,但我只想序列化然后反序列化ClassA1.ID成员,然后在反序列化时从我的固定列表中检索对象引用。

自动序列化给了我这个:

...
<ClassA2>
  <ID>IDStringForObjectClassA2</ID>
  <Details>
    <ClassA1>
      <ID>IDStringForObjectOfClassA1</ID>
      <Name>MyNameValue</Name>
      <Value>MyStringValue</Value>
      <Description>MyDescriptionValue</Description>
    </ClassA1>
  </Details>
  <SomeValue>0</SomeValue>
</ClassA2>

我想要的最终结果是

...
<ClassA2>
  <ID>IDStringForObjectClassA2</ID>
  <Details>
    <ClassA1>
      <ID>IDStringForObjectOfClassA1</ID>
    </ClassA1>
  </Details>
  <SomeValue>0</SomeValue>
</ClassA2>

并且在对ClassA1.ID成员进行反序列化时,我想在预加载列表中找到一个实际对象

编辑:下面的文档序列化程序类

public class Document
{
  private _ClassA2;

  public Document() { _ClassA2 = null; }

  public ClassA2 ClassA2
  {
    get { return _ClassA2; }
    set { _ClassA2 = value; }
  }

  public string Serialize(StreamWriter writer)
  {
    var serializer = new XmlSerializer(typeof(ClassA2));
    serializer.Serialize(writer, this);
    return writer.ToString();
  }

  public static ClassA2 DeSerialize(StreamReader reader)
  {
    var serializer = new XmlSerializer(typeof(ClassA2 ));
    ClassA2 value = serializer.Deserialize(reader) as ClassA2 ;
    return value;
  }
}

2 个答案:

答案 0 :(得分:2)

要排除元素,您可以在与数据相同的类中定义“ShouldSerialize”方法:

public bool ShouldSerializeDescription()
{
    return false;
}

public decimal Description { get; set; }

或使用属性上方的[XmlIgnore]属性:

[XmlIgnore]
public decimal Description { get; set; }

在大多数情况下,我建议使用XmlIgnore。

关于定位一个成员来填充该字段,就我所知,没有内置任何东西来实现这一点。您只需循环并手动定位值。有关详细信息,请参阅this post

答案 1 :(得分:1)

我更改了输入XMl,它稍微被序列化以使其成为有效的XML。请参阅以下代码,该代码仅对ID属性中存在的ClassA1 Details属性进行反序列化。您必须在代码文件的顶部使用以下导入using System.Xml.Linq;

private static void NestedMemberSerialization()
{

    var serializedXml = "<ClassA2><ID>1</ID><Details><ClassA1><ID>2</ID><Name>4</Name><Value>2</Value><Description>3</Description></ClassA1></Details><SomeValue>2</SomeValue></ClassA2>";

    XDocument doc = XDocument.Parse(serializedXml);

    var mySteps = (from s in doc.Descendants("ClassA2")
                   select new ClassA2
                   {
                       ID = decimal.Parse( s.Element("ID").Value),
                       SomeValue = int.Parse( s.Element("SomeValue").Value),
                       Details = new ClassA1 { ID = decimal.Parse(s.Element("Details").Descendants("ClassA1").Descendants("ID").ElementAt(0).Value) }
                   }).ToList();

}