一、如何让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文件: