带有IXmlSerializable的自定义类因OutOfMemoryException而失败

时间:2017-10-09 14:22:46

标签: c# xml xml-serialization

我有以下xml文件:

$categories

我使用以下帮助方法加载它:

class Time
  # Convert the time to the FILETIME format, a 64-bit value representing the
  # number of 100-nanosecond intervals since January 1, 1601 (UTC).
  def wtime
    self.to_i * 10000000 + (self.tv_nsec/100.0).round + 116444736000000000
  end

  # Create a time object from the FILETIME format, a 64-bit value representing
  # the number of 100-nanosecond intervals since January 1, 1601 (UTC).
  def self.from_wtime(wtime)
    Time.at((wtime - 116444736000000000) / 10000000,
            ((wtime - 116444736000000000) % 10000000)/10.0)
  end
end

这是wtime = 131172192735329876 #=> 131172192735329876 t = Time.from_wtime(wtime) #=> 2016-09-01 12:01:13 -0400 t.wtime #=> 131172192735329876 t.wtime == wtime #=> true Time.now.wtime #=> 131520319622603520

<MyConfig>
  <Item a1="Attrib11" a2="Attrib21" a3="Attrib31" />
  <Item a1="Attrib12" a2="Attrib22" a3="Attrib32" />
</MyConfig>

然后我有以下测试床代码来检查类的序列化:

public static T Load<T>(string path)
{
    XmlSerializer xml = new XmlSerializer(typeof(T));

    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
    using (StreamReader sr = new StreamReader(fs))
    {
        return (T)xml.Deserialize(sr);
    }
}

public static void Save<T>(string path, T contents)
{
    XmlSerializer xml = new XmlSerializer(typeof(T));

    using (FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
    using (StreamWriter sw = new StreamWriter(fs))
    {
        xml.Serialize(sw, contents, ns);
    }
}

这在MyConfig处出现OutOfMemory异常失败,我该如何解决这个问题?检查public class MyConfig { [XmlElement("Item")] public List<Item> Items { get; set; } public MyConfig() { Items = new List<Item>(); } } public class Item : IXmlSerializable { [XmlAttribute()] public string Attrib1 { get; set; } [XmlAttribute()] public string Attrib2 { get; set; } [XmlAttribute()] public string Attrib3 { get; set; } public Item(string attrib1, string attrib2, string attrib3) { Attrib1 = attrib1; Attrib2 = attrib2; Attrib3 = attrib3; } public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { Attrib1 = reader.GetAttribute("a1"); Attrib2 = reader.GetAttribute("a2"); Attrib3 = reader.GetAttribute("a3"); } } public void WriteXml(XmlWriter writer) { writer.WriteAttributeString("a1", Attrib1); writer.WriteAttributeString("a2", Attrib2); writer.WriteAttributeString("a3", Attrib3); } } 处的文件,看起来是正确的。

1 个答案:

答案 0 :(得分:2)

在您阅读完属性后,您需要告诉reader前进到下一个节点:

public void ReadXml(XmlReader reader)
{
    if (reader.MoveToContent() == XmlNodeType.Element)
    {
        Attrib1 = reader.GetAttribute("a1");
        Attrib2 = reader.GetAttribute("a2");
        Attrib3 = reader.GetAttribute("a3");
    }
    // Go to the next node.
    reader.Read();
}

如果您不打电话给reader.Read()reader会一遍又一遍地读取同一节点,因此XmlSerializer会创建无限量的Item实例,直到你最终得到OutOfMemoryException