c# - 具有 IXmlSerializable 的自定义类因 OutOfMemoryException 而失败

标签 c# xml xml-serialization

我有以下 xml 文件:

<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:

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

然后我有以下用于检查类序列化的测试台代码:

string file = "somePath";

MyConfig myConfig = new MyConfig()
{
    Items = new List<Item>()
    {
        new Item("Attrib11", "Attrib21", "Attrib31"),
        new Item("Attrib12", "Attrib22", "Attrib32"),
    },
};

Save(file, myConfig);

MyConfig myConfig2 = Load<MyConfig>(file);

此操作因 Load 中的 OutOfMemory 异常而失败,我该如何解决?检查位于 somePath 的文件,它看起来是正确的。

最佳答案

在读取属性后,您需要告诉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

关于c# - 具有 IXmlSerializable 的自定义类因 OutOfMemoryException 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46648730/

相关文章:

c# - 自动隐藏 MenuStrip - 显示时如何激活它?

html - mozila 中的 XSLT 转换将 &lt;!DOCTYPE> 标记视为纯文本并显示在网页上

javascript - node.setAttribute ('attName' ,null) 返回类型不匹配

java - ReSTLet:在 HTTP 请求中发送 xml

c# - XML 反序列化缺失元素

c# - C# 中是否存在可使局部变量在多次调用中保持不变的关键字?

.net - 带有命名空间的 XML 的 XPath

java - Java 中的序列化对象

.net - XmlSerializer和System.Drawing.Color的最佳解决方案

c# - MVC 比较属性在服务器端不起作用