C#对字典容器Dictionary<TKey, TValue>内容进行XML序列化或反序列化报错解决方法

news2024/11/15 17:14:59

一、问题描述

        在使用C#对字典容器Dictionary<TKey, TValue>内容进行XML序列化报错【System.Exception:“不支持类型 System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],因为它实现 IDictionary。”】如下所示:

 

或反序列化操作时会报如下错误【System.Exception:“不支持类型 System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],因为它实现 IDictionary。”】如下图所示

二、问题分析

        通过异常信息可以看到是由于XML序列化或反序列化程序导致报错,且该错误是由于IDictionary导致,通过反编译查看【System.Xml.Serialization.TypeScope】内容可以发现代码直接对IDictionary类型直接做返回异常处理,不让序列化或反序列化。

三、解决方法

1、创建一个新的类【DictionaryEx】,继承Dictionary<TKey, TValue>类和IXmlSerializable接口:

using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Kernal
{
    #region 可序列化字典类 + public class DictionaryEx<TKey, TValue>
    /// <summary>
    /// 可序列化字典类
    /// </summary>
    /// <typeparam name="TKey">键泛型</typeparam>
    /// <typeparam name="TValue">值泛型</typeparam>
    [System.Serializable]
    public class DictionaryEx<TKey, TValue>
      : Dictionary<TKey, TValue>, IXmlSerializable
    {
        #region 构造函数

        #region 默认构造函数 + public DictionaryEx()
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public DictionaryEx()
            : base()
        {

        }
        #endregion

        #region 构造函数 + public DictionaryEx(int capacity)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="capacity">可包含的初始元素数</param>
        public DictionaryEx(int capacity)
            : base(capacity)
        {

        }
        #endregion

        #region 构造函数 + public DictionaryEx(IEqualityComparer<TKey> comparer)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="comparer">比较键时要使用的 比较器 实现,或者为 null,以便为键类型使用默认的 比较器</param>
        public DictionaryEx(IEqualityComparer<TKey> comparer)
            : base(comparer)
        {

        }
        #endregion

        #region 构造函数 + public DictionaryEx(IDictionary<TKey, TValue> dictionary)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dictionary">初始数据</param>
        public DictionaryEx(IDictionary<TKey, TValue> dictionary)
            : base(dictionary)
        {

        }
        #endregion

        #region 构造函数 + public DictionaryEx(int capacity, IEqualityComparer<TKey> comparer)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="capacity">可包含的初始元素数</param>
        /// <param name="comparer">比较键时要使用的 比较器 实现,或者为 null,以便为键类型使用默认的 比较器</param>
        public DictionaryEx(int capacity, IEqualityComparer<TKey> comparer)
            : base(capacity, comparer)
        {

        }
        #endregion

        #region 构造函数 + public DictionaryEx(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dictionary">初始数据</param>
        /// <param name="comparer">比较键时要使用的 比较器 实现,或者为 null,以便为键类型使用默认的 比较器</param>
        public DictionaryEx(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
            : base(dictionary, comparer)
        {

        }
        #endregion

        #endregion

        #region 取得概要 + public XmlSchema GetSchema()
        /// <summary>
        /// 取得概要
        /// 注:根据MSDN的文档,此方法为保留方法,一定返回 null。
        /// </summary>
        /// <returns>Xml概要</returns>
        public XmlSchema GetSchema()
        {
            return null;
        }
        #endregion

        #region 从 XML 对象中反序列化生成本对象 + public void ReadXml(XmlReader reader)
        /// <summary>  
        /// 从 XML 对象中反序列化生成本对象
        /// </summary>  
        /// <param name="reader">包含反序列化对象的 XmlReader 流</param>  
        public void ReadXml(XmlReader reader)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
            bool wasEmpty = reader.IsEmptyElement;
            reader.Read();
            if (wasEmpty) return;

            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("Item");
                reader.ReadStartElement("Key");
                TKey key = (TKey)keySerializer.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadStartElement("Value");
                TValue value = (TValue)valueSerializer.Deserialize(reader);
                reader.ReadEndElement();
                this.Add(key, value);
                reader.ReadEndElement();
                reader.MoveToContent();
            }

            reader.ReadEndElement();
        }
        #endregion

        #region 将本对象序列化为 XML 对象 + public void WriteXml(XmlWriter writer)
        /// <summary>  
        /// 将本对象序列化为 XML 对象
        /// </summary>  
        /// <param name="writer">待写入的 XmlWriter 对象</param>  
        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
            foreach (TKey key in this.Keys)
            {
                writer.WriteStartElement("Item");
                writer.WriteStartElement("Key");
                keySerializer.Serialize(writer, key);
                writer.WriteEndElement();
                writer.WriteStartElement("Value");
                TValue value = this[key];
                valueSerializer.Serialize(writer, value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }
        #endregion
    }
    #endregion
}

  2、将原来使用Dictionary的类替换为DictionaryEx类

        /// <summary>
        /// 保存语言信息
        /// </summary>
        private bool SaveFileExpandNameList(DictionaryEx<string,string> languageInfoDic, string languageFilePathAndName)
        {
            bool success = false;
            if (languageInfoDic != null && languageInfoDic.Count >= 0)
            {
                //将对象序列化为xml字符串
                string strXml = XmlHelper.ObjectToXml2(languageInfoDic);
                if (!string.IsNullOrEmpty(strXml))
                {
                    //先清空文件
                    FileOPC.Clear(languageFilePathAndName);
                    //保存Json字符串文件(覆盖写入)
                    success = FileOPC.OverWrite(languageFilePathAndName, strXml);
                }
            }
            return success;
        }


        /// <summary>
        /// 获取语言信息
        /// </summary>
        /// <returns>返回语言信息字典</returns>
        private DictionaryEx<string, string> GetLanguageInfo(string languageFilePathAndName)
        {
            if (string.IsNullOrEmpty(languageFilePathAndName)) return null;

            DictionaryEx<string, string> languageInfoDic = new DictionaryEx<string, string>();

            //读取xml文件字符串
            string strXml = FileOPC.Read(languageFilePathAndName);

            //读取xml文件并序列化为对象
            languageInfoDic = XmlHelper.XmlToObject2<DictionaryEx<string, string>>(strXml);

            return languageInfoDic;
        }

3、序列化DictionaryEx<TKey, TValue>容器内容的XML内容如下所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1074571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣刷题 day39:10-09

1.统计有序矩阵中的负数 给你一个 m * n 的矩阵 grid&#xff0c;矩阵中的元素无论是按行还是按列&#xff0c;都以非递增顺序排列。 请你统计并返回 grid 中 负数 的数目。 方法一&#xff1a;二分法 #方法一&#xff1a;二分法 def countNegatives(grid):res0for nums in…

Altium Designer实用系列(二)----PCB绘图小技巧

一、技巧总结 1.1 丝印大小 在导入PCB之后&#xff0c;元器件的丝印一般都是strock font&#xff0c;个人感觉比较大&#xff0c;也不美观&#xff0c;但是一个个修改成true type又比较麻烦。简便方法是使用相似查找全部修改:   此时会选中所有stroke 类型的丝印&#xff…

提高工作效率!本地部署Stackedit Markdown编辑器,并实现远程访问

文章目录 1. docker部署Stackedit2. 本地访问3. Linux 安装cpolar4. 配置Stackedit公网访问地址5. 公网远程访问Stackedit6. 固定Stackedit公网地址 StackEdit是一个受欢迎的Markdown编辑器&#xff0c;在GitHub上拥有20.7k Star&#xff01;&#xff0c;它支持将Markdown笔记保…

git命令笔记

git命令笔记 前言&#xff1a;git对于软件开发和协作的重要性不言而喻&#xff0c;在企业开发中&#xff0c;git命令和linux命令的使用同样重要。作为开发者&#xff0c;需要牢记并熟练使用常见的git命令 git工作流程图 命令如下&#xff1a; clone&#xff08;克隆&#xf…

论文解析——异构多芯粒神经网络加速器

作者 朱郭益, 马胜&#xff0c;张春元, 王波&#xff08;国防科技大学计算机学院&#xff09; 摘要 随着神经网络技术的快速发展, 出于安全性等方面考虑, 大量边缘计算设备被应用于智能计算领域。首先&#xff0c;设计了可应用于边缘计算的异构多芯粒神经网络加速器其基本结构…

C++ - 可变模版参数 - emplace相关接口函数 - 移动构造函数 和 移动赋值运算符重载 的 默认成员函数

可变模版参数 我们先来了解一下&#xff0c;可变参数。可变参数就是在定义函数的时候&#xff0c;某一个参数位置使用 "..." 的方式来写的&#xff0c;在库当中有一个经典的函数系列就是用的 可变参数&#xff1a;printf&#xff08;&#xff09;系列就是用的可变参…

基于SSM的个人博客系统

实现内容 本系统为用户提供实现了以下功能&#xff1a; 1.登录功能&#xff1a; 系统为单用户系统&#xff0c;为用户分配了用户名和密码。用户必须先登录&#xff0c;进入操作界面。用户输入ID和密码&#xff0c;通过服务器验证方可运行&#xff0c;否则显示消息提示。 2.…

Netron【.pt转.onnx模型展示】

接着上一篇写哈&#xff0c;如何转.onnx的。 因为是转.onnx类型的&#xff0c;需要先安装onnx的包。 这是直接pip install onnx后转onnx报的错&#xff1a; 很显然是版本问题导致的&#xff0c;so: 将export.py的脚本拉到最下面的parse_opt函数&#xff0c;把“17”改为“12”…

解读非托管流动性协议Hover: 差异化、层次化的全新借贷体系

“Hover 是 DeFi 借贷赛道的另辟蹊径者&#xff0c;除了在自身机制&#xff08;借贷模型、治理体系&#xff09;上进行创新获得内生动力外&#xff0c;背靠日渐繁荣的 Kava、Cosmos 生态进一步获得外生动力&#xff0c;发展潜力俱佳” 与 DEX 类似&#xff0c;借贷也是 DeFi 世…

对于L1正则化和L2正则化的理解

在DL中&#xff0c;L1和L2正则化经常被使用到&#xff0c;因为大于1L的正则化都是凸优化的问题&#xff0c;是个简单问题&#xff0c;可以被解决。 首先说正则的意义&#xff1a; 一切可以缓解过拟合的方法&#xff0c;都可以被叫做正则化 我最开始理解正则化的时候就是看lh…

数学分析:含参变量的积分

同样很多收敛性的证明不是重点&#xff0c;但里面的知识还是需要适当掌握&#xff0c;知道中间的大致思考和解决路径即可。 本质还是极限的可交换性&#xff0c;求导可以换到积分里面去操作。 这里要注意变量的区别&#xff0c;首先积分的被积变量是x&#xff0c;但是函数的变量…

小红书婴童产业探索,解析消费者需求!

在消费升级、市场引导的背景下&#xff0c;众多产业都在悄然发生着变化&#xff0c;其中“婴童产业”就是非常有代表性的一个。今天就来深入分析小红书婴童产业探索&#xff0c;解析消费者需求&#xff01; 一、何为婴童产业 事实上&#xff0c;婴童产业&#xff0c;并不仅仅局…

java中线程池的使用+优雅的spring释放资源

1.定义一个接口 package com.zsp.quartz.service;public interface ScheduledService {void setInfo(); }2.定义实现类 package com.zsp.quartz.service.impl;import com.alibaba.fastjson.JSON; import com.zsp.quartz.entity.User; import com.zsp.quartz.service.Schedul…

弹性资源组件elastic-resource设计(四)-任务管理器和资源消费者规范

简介 弹性资源组件提供动态资源能力&#xff0c;是分布式系统关键基础设施&#xff0c;分布式datax&#xff0c;分布式索引&#xff0c;事件引擎都需要集群和资源的弹性资源能力&#xff0c;提高伸缩性和作业处理能力。 本文介绍弹性资源组件的设计&#xff0c;包括架构设计和详…

ctfshow-web11(session绕过)

php代码审计&#xff1a; function replaceSpecialChar($strParam){$regex "/(select|from|where|join|sleep|and|\s|union|,)/i";return preg_replace($regex,"",$strParam);} 首先定义了一个函数&#xff0c;主要是使用preg_replace函数对我们提交的内…

【C++设计模式之解释器模式:行为型】分析及示例

简介 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供了一种解决问题的方法&#xff0c;通过定义语言的文法规则&#xff0c;解释并执行特定的语言表达式。 解释器模式通过使用表达式和解释器&#xff0c;将文法规则中的句子逐…

用 HTTP 提交数据,基本就这 5 种方式

网页开发中&#xff0c;向服务端提交数据是一个基本功能&#xff0c;工作中会大量用 xhr/fetch 的 api 或者 axios 这种封装了一层的库来做。 可能大家都写过很多 http/https 相关的代码&#xff0c;但是又没有梳理下它们有哪几种呢&#xff1f; 其实通过 http/https 向服务端…

SQL Server 简介与 Docker Compose 部署

今天我翻阅了在之前公司工作时的笔记&#xff0c;发现了有关数据库的一些记录。当时&#xff0c;我们的项目开始使用 Oracle 数据库&#xff0c;但后来由于一些项目需求的变更&#xff0c;我们切换到了 SQL Server 。值得一提的是&#xff0c;公司当时也开始采用 Docker 技术&a…

基于matlab统计Excel文件一列数据中每个数字出现的频次和频率

一、需求描述 如上表所示&#xff0c;在excel文件中&#xff0c;有一列数&#xff0c;统计出该列数中&#xff0c;每个数出现的次数和频率。最后&#xff0c;将统计结果输出到新的excel文件中。 二、程序讲解 第一步&#xff1a;选择excel文件&#xff1b; [Filename, Pathn…

VBox启动失败、Genymotion启动失败、Vagrant迁移

VBox启动失败、Genymotion启动失败、Vagrant迁移 2023.10.9 最新版本vbox7.0.10、Genymotion3.5.0 Vbox启动失败 1、查看日志 Error -610 in supR3HardenedMainInitRuntime! (enmWhat4) Failed to locate ‘vcruntime140.dll’ 日志信息查看方法->找到虚拟机所在位置->…