首页 > 编程语言 >C#中泛型集合List<T>反序列化问题及解决方法

C#中泛型集合List<T>反序列化问题及解决方法

时间:2023-09-02 21:01:27浏览次数:34  
标签:C# List 泛型 类型 软件 序列化 方法

一、普通类型的反序列化程序集问题及处理方法

在一些应用系统中常常有两个子系统软件A与B:A软件序列化一个数据文件,该文件将在B软件中使用。例如,在15年的交通运输部小样本调查数据的审核软件中,A软件就是笔者自己用的审核规则编制软件;B软件则是给用户使用的审核小样本调查数据的客户端软件,该软件只需要使用A软件发布的规则即可。笔者的处理方法是,A软件序列化审核规则DataTable到一个文件中,B软件反序列化该文件后直接使用。

一般情况下,A软件序列化类型对象时,将写入类型的名称,且该名称包含了程序集的名字(注意,这个是关键),并且B软件通常不与A软件的程序集名相同。因此,在反序列化时将抛出:“处理的异常: System.Runtime.Serialization.SerializationException: 无法找到程序集“ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”。这里的异常信息中的ConsoleApplication1就是A软件的程序集名。这类异常的解决方法是:在反序列化时,更改类型查找的程序集名。具体代码如下:

using (FileStream fs = new FileStream("student.dat", FileMode.Open, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new LocalizedTypeGetter(); // 保证在当前程序集中获取反序列化的类型
Students newObj = (Students)bf.Deserialize(fs); // 这里假设 Students 是一个普通类型
Console.WriteLine(newObj.Name);
}
public class LocalizedTypeGetter : System.Runtime.Serialization.SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
assemblyName = System.Reflection.Assembly.GetExecutingAssembly().FullName; // 当前程序集
return Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)); // 从当前程序集中获取类型名,注意,类型的名称空间要相同
}
}
在反序列化时,给序列化类的Binder方法一个自定义的类型LocalizerTypeGetter,该类型重写了BindToType()方法,保证在当前程序集中获取类型。
这里需要强调的是,反序列化和序列化程序集应该是相同的名称空间(不同的名称空间是否可行?笔者尚未做相关测试,因为笔者的AB软件的名称空间是相同的)。
二、泛型集合List<T>的反序列化问题及处理方法
前面介绍的方法不能解决泛型集合List<T>的反序列化问题。因为List<T>被.NET框架认为是标准类型,将在mscorlib动态库中查找类型,而不是在用户程序集中查找类型,笔者通过调试跟踪BindToType()方法发现了这个现象。在尚未找到通用方式前,笔者采取了如下“笨”的直接方法解决:

public class LocalizedTypeGetterEx : LocalizedTypeGetter
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.Contains("List") == true && typeName.Contains(typeof(Student).Name) == true) // 如果是泛型集合
{
return typeof(List<Student>); // 直接返回反序列化的类型
}

return base.BindToType(assemblyName, typeName);
}
}
派生LocalizedTypeGetter类型,再次重写BindToType()方法。在再重写方法中,判断是否是反序列化需要的泛型集合,如果是则直接返回泛型结合的类型List<T>(如代码中的List<Student>)。此时,只需要在反序列化时修改代码为 bf.Binder = new LocalizedTypeGetterEx()即可。

上述代码在Win7、Visual Studio 2012、.NET Framework3.5环境下调试通过。

补充:在设计15年小样本调查数据处理软件时,使用了DataTable保存审核规则,反序列化和序列化只需要考虑上面一般类型的反序列化方法即可。然而,最近在做公路养护报表审核软件时,使用泛型List<T>保存审核规则记录,在序列化和反序列化时就碰到了反序列化失败的异常。暂时找到的方法是笨方法,希望以后改进为通用方法。
————————————————
版权声明:本文转载自CSDN博主「长沙三毛」。
原文链接:https://blog.csdn.net/hulihui/article/details/48967971

标签:C#,List,泛型,类型,软件,序列化,方法
From: https://www.cnblogs.com/soliang/p/17674188.html

相关文章

  • c++ 堆排序
    堆排序主要分为两个函数:1、构建堆2、元素调整#include<iostream>usingnamespacestd;voidmaxHeap(inttree[],intn,inti){ if(i>=n) return; intlchild=i*2+1; intrchild=i*2+2; intmax=i; if(lchild<n&&tree[lchild]>t......
  • 在Docker下一键安装部署免费开源的问答社区!
    在Docker下一键安装部署免费开源的问答社区! 1.准备一台VPS主机,没有的话,【搞一台】 2.一键安装部署Dockerwgethttps://raw.githubusercontent.com/QUANTAXIS/QUANTAXIS/master/config/install_docker.shsudobashinstall_docker.sh全选代码复制3.一键安装Answ......
  • 什么是敏捷开发中的scrum模型?
    Scrum是一种敏捷软件开发的框架。敏捷开发是一种迭代和增量的开发方法,它强调灵活性、快速反应和客户协作。Scrum特别适合于处理那些需求不断变化,或者不太清楚需求的复杂项目。它是一个轻量级的过程框架,用于管理复杂的创新性工作,它提高了团队之间的沟通和协作......
  • Oracle-UNDO数据文件被创建在本地
    在Oracle的RAC环境中,UNDO表空间也是被创建在ASM。假如,UNDO表空间的数据文件,有一个被创建在了本地,那如何处理呢?1.删除数据文件会提示ORA-03262:thefileisnon-empty2.正确的方法A.创建新的UNDO表空间createundotablespaceUNDOTBS3datafile'+DATA'size1g;B.切换到新的UNDO......
  • Crontab命令详解
    Linux系统则是由cron(crond)这个系统服务来控制的。Linux系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的。另外,由于使用者自己也可以设置计划任务,所以,Linux系统也提供了使用者控制计划任务的命令:crontab命令。一、crond简介crond 是linux下用来周期......
  • 东方博宜OJ1009 数组逆序 C语言版
    题目描述给你 n 个整数,将其逆序输出。输入第一行一个整数 n (3≤n≤100)代表数的个数。第二行 n 个整数(空格隔开)(这些数在 0∼106 之间)。输出n 个整数(空格隔开)。样例输入3175输出571来源数组问题代码 #include<stdio.h>in......
  • Educational Codeforces Round 154 (Rated for Div. 2)
    Preface太FW了现在,纯纯给队伍拖后腿,马上要成为我们队CFRating最低的了但换句话说徐神和祁神都这么猛,我直接躺着被嘎嘎带飞好像也很爽啊不管怎么样还是要多练,不过接下来可能要按专题重点突破了,明天队里开个会确定下大家的主攻方向再说A.PrimeDeletion因为\(13\)和\(31\)都......
  • C++ Core Guidelines解析 电子书 pdf
    关注公众号:红宸笑。回复:电子书即可  在《C++CoreGuidelines解析》中,C++专家讲师RainerGrimm提炼出了CoreGuidelines中的精髓,去除了晦涩难懂的内容,分享了新的见解和背景,并提供了自己培训课程中经过充分测试的示例。对于使用C++11及后续版本C++的有经验程序员,G......
  • Implementing Domain Driven Design (A practical guide for implementing the Domain
    CONTENTSIntroduction..................................................Goal......................................................SimpleCode...................................................................WhatistheDomainDrivenDesign?...........
  • Note of SHU Computer Graphics (01): 计算机图形学概述
    什么是计算机图形学?研究怎样利用计算机来显示、生成和处理图形的原理、方法和技术的一门学科,这里的图形是指三维图形的处理。图形:计算机图形学的研究对象能在人的视觉系统中产生视觉印象的客观对象包括自然景物、拍摄到的图片、用数学方法描述的图形等等构成图形的要......