【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文件:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值