我有一个相当大的对象图,我通过DataContractSerializer序列化到一个文件。我现在想要向用户提供这些文件的列表以供选择。在此列表中,我想显示有关该文件的一些详细信息,这些属性是根对象的属性。我不想将整个图形加载到内存中,因为我只对显示根节点的属性感兴趣。

有没有人知道控制“深度”的方法。反序列化,以便我可以从文件中拉出根对象并跳过孩子们?我宁愿避免将文件视为原始XML,因为我没有在其他任何地方进行任何原始的XML操作,这将是我必须保持同步的另一个代码分支。

我现在唯一的想法是创建一个兼容的“摘要”。对象只包含我感兴趣的属性,没有子节点,并将文件反序列化为该对象。这应该跳过子项,因为它们与摘要对象无关。

有没有更好的方法来实现这一目标?

更新/澄清:属性不是我正在寻找的答案。一方面,他们会阻止“额外”的首次序列化对象时,在文件中结束的属性。

其次,它们比我想做的更持久。最后,我确实希望反序列化整个文件,而不是在此时。我正在尝试显示用户将从中进行导入的文件摘要列表。在进口过程中,我将需要所有的孩子和孙子。在第1步中它只是矫枉过正。这些都是潜在的大文件,所以完全反序列化其中的几个,这样我才能显示它们的标题信息是行不通的。

希望能够解决对原始问题的任何困惑。

有帮助吗?

解决方案

这就是你想要的方式。 DataContractSerializer旨在处理这种情况,在这种情况下,您必须从概念上相同的类型,但从CLR的角度来看,您希望彼此序列化的类型不同。

鉴于此,只需使用您要序列化的类似属性子集创建对象,并将该类型传递给DataContractSerializer。

确保在“摘要”上您设置DataContract属性的属性的类型(以及您公开的子项上的任何DataMember属性或DataContract属性),特别是Name和Namespace属性,以反映非汇总类型的名称和命名空间(因为这些必须匹配)

其他提示

如果您只是想从根节点中提取一些细节,我的第一个建议是进行XML操作。另一种可能性,虽然我不知道性能影响,但是使用DataContractSerializer的版本控制功能来解决这个问题。在数据合同上,将摘要中除了您需要的字段外的每个字段标记为可选。然后,将数据协定复制为另一个类,省略可选字段。反序列化为新的较小数据协定。

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}

您可以使用属性控制序列化。 阅读更多此处

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top