【Unity数据持久化】让XmlSerializer支持对Dictionary进行序列化和反序列化

一、如何让Dictionary支持Xml序列化和反序列化?

1.我们无法修改C#自带的类
2.那我们可以重写一个类,继承Dictionary,然后让这个类继承序列化拓展接口IXmlSerializable
3.实现接口中的序列化和反序列化方法即可

二、开干

第一步:重写一个类,继承Dictionary,并让这个类继承序列化拓展接口IXmlSerializable

using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using UnityEngine;
public class SerizlizerDictionary<TKey, TValue> : Dictionary<TKey, TValue>,  IXmlSerializable
{
    
    
    public XmlSchema GetSchema()
    {
    
    
        return null;
    }

    /// <summary>
    /// 自定义字典的序列化规则
    /// </summary>
    /// <param name="writer"></param>
    public void WriteXml(XmlWriter writer)
    {
    
    
        //声明键和值的“翻译器”
        XmlSerializer keySer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        //遍历自己的键和值
        foreach (KeyValuePair<TKey, TValue> kv in this)
        {
    
    
            //对键值对序列化
            keySer.Serialize(writer, kv.Key);
            valueSer.Serialize(writer, kv.Value);
        }
    }

    /// <summary>
    /// 自定义字典的反序列化规则
    /// </summary>
    /// <param name="reader"></param>
    public void ReadXml(XmlReader reader)
    {
    
    
        //声明键和值的“翻译器”
        XmlSerializer keySer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        //跳过根节点
        reader.Read();
        //只要没读到End节点 就一直读
        while (reader.NodeType != XmlNodeType.EndElement)
        {
    
    
            //解析键
            TKey key = (TKey)keySer.Deserialize(reader);
            //解析值
            TValue value = (TValue)valueSer.Deserialize(reader);
            //把读到的值加进去
            this.Add(key, value);
        }
        //把End节点读了,避免影响之后的数据读取
        reader.Read();
    }
}

第二步:准备数据并测试

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

//测试用自定义类
public class PlayerInfo
{
    
    
    public int lv;
    public SerizlizerDictionary<int, string> dic;
}
public class Lesson4 : MonoBehaviour
{
    
    
    void Start()
    {
    
    
        //测试序列化
        PlayerInfo p = new PlayerInfo();
        p.dic = new SerizlizerDictionary<int, string>();
        p.dic.Add(1, "黑暗剑");
        p.dic.Add(2, "月光大剑");
        //序列化路径
        string path = Application.persistentDataPath + "/PlayerInfo2.xml";
        using (StreamWriter writer = new StreamWriter(path))
        {
    
    
            //声明“翻译器”
            XmlSerializer s = new XmlSerializer(typeof(PlayerInfo));
            //序列化
            s.Serialize(writer, p);
        }

        //测试反序列化
        PlayerInfo p2 = new PlayerInfo();
        using (StreamReader reader = new StreamReader(path))
        {
    
    
            //声明“翻译器”
            XmlSerializer s = new XmlSerializer(typeof(PlayerInfo));
            p2 = s.Deserialize(reader) as PlayerInfo;
        }
    }
}

序列化后保存的xml文件:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/SEA_0825/article/details/127200906
今日推荐