【问题标题】:Nested class member serialization嵌套类成员序列化
【发布时间】:2017-04-05 06:47:39
【问题描述】:

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

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>

我想要的 XML 最终结果是这样的

...
<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;
  }
}

【问题讨论】:

  • 您当前用于反序列化的代码是什么?
  • 根据您提到的类,您的 XML 对反序列化无效。 Details 标签里面应该有一个ClassA1 标签。 ClassA2 也没有结束标签。
  • @RBT 我正在使用标准的 XmlSerializer 类进行反序列化,无论如何要将上述内容合并到此中,还是我必须更改为完全自定义的反序列化 var serializer = new XmlSerializer(typeof(CableDocument)); CableDocument value = serializer.Deserialize(reader) as CableDocument; 编辑:终生我无法让降价在上面正常工作
  • 请将您当前的代码添加到您的帖子中。最好将问题的所有内容都保留在帖子中而不是 cmets 中。请改为将您的编辑放入您的帖子中。您能否将CableDocument 类的定义添加到您的帖子中。
  • @RBT 编码编辑

标签: c# serialization


【解决方案1】:

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

public bool ShouldSerializeDescription()
{
    return false;
}

public decimal Description { get; set; }

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

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

在大多数情况下,我会推荐 XmlIgnore。

关于查找要填充字段的成员,据我所知,没有任何内置功能可以实现这一点。您只需要手动循环并找到值。请参阅this post 了解更多信息。

【讨论】:

  • John,我没有使用 XmlIgnore 或 ShouldSerialize 的原因是因为 ClassA1 单独序列化并且需要序列化这些字段。我遇到的问题是在序列化包含嵌套类的类时。主类(ClassA2)只需要序列化和反序列化一个ID,这样引用嵌套类的成员变量就可以引用相应的ClassA1对象一个单独反序列化的对象列表。
  • 提供的链接似乎引用了我想要实现的目标,因此我也会查看该线程中提供的选项。
【解决方案2】:

我更改了输入 XMl,它被序列化了一点,以使其成为有效的 XML。请参阅下面的代码,该代码仅反序列化 ClassA1ID 属性,存在于 Details 属性中。您必须在代码文件顶部使用以下 import 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();

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    相关资源
    最近更新 更多