C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案
C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案
新建Console控制台项目项目,然后添加Team和Person 这2个类,如下:
Team和Person 这2个类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks; namespace SupremeConsole
{
[Serializable]
public class Team
{ /// <summary>
/// 队名
/// </summary>
public string TName { get; set; } /// <summary>
/// 选手
/// </summary>
public List<Person> PlayerList = new List<Person>();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks; namespace SupremeConsole
{
[Serializable]
public class Person
{
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; } /// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
}
}
使用Binary或者Soap进行序列化,本例演示使用Soap对类型种的泛型字段进行序列化,代码如下:
using System;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.IO.MemoryMappedFiles;
using System.IO.Pipes;
using System.Linq;
using System.Net;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Runtime.Serialization; namespace SupremeConsole
{
class Program
{
static void Main(string[] args)
{
TestSeri();
Console.ReadLine();
} public static void TestSeri() {
Team team = new Team { TName="",PlayerList = { new Person { Name="",Age=},new Person { Name = "", Age = } } };
#region BinarySerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
//string s = SerializeManager.Instance.BinarySerialize<Team>(team);//序列化
//Console.ForegroundColor = ConsoleColor.Green;
//Console.WriteLine("测试序列化成功。。。");
//Console.WriteLine($"测试序列化结果:\r\n{s}"); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");//序列化
//SerializeManager.Instance.BinarySerialize<Team>(team, path); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");
//Team test = SerializeManager.Instance.BinaryDeserialize<Team>(path);//反序列化
//if (test != null)
//{
// Console.WriteLine($"测试序列化结果:{test.ToString()}");
//}
#endregion #region SoapSerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
string s = SerializeManager.Instance.SoapSerialize<Team>(team);//序列化
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("测试序列化成功。。。");
Console.WriteLine($"测试序列化结果:\r\n{s}"); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");//序列化
//SerializeManager.Instance.SoapSerialize<Team>(team, path); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");
//Team test = SerializeManager.Instance.SoapDeserialize<Team>(path);//反序列化
//if (test != null)
//{
// Console.WriteLine($"测试序列化结果:{test.ToString()}");
//}
#endregion
}
/// <summary>
/// Binary泛型序列化
/// </summary>
/// <typeparam name="T">泛型类型</typeparam>
/// <param name="t">泛型对象</param>
/// <returns>泛型对象序列化的字符串</returns>
public string BinarySerialize<T>(T t) where T : class
{
string s = null;
try
{
using MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, t);
s = Encoding.UTF8.GetString(ms.ToArray());
}
catch (Exception ex)
{
Program.Log.Error($"Binary泛型序列化错误信息:{ex.ToString()}");
}
return s;
} /// <summary>
/// Binary泛型序列化
/// </summary>
/// <typeparam name="T">泛型类型</typeparam>
/// <param name="t">泛型对象</param>
/// <param name="path">保存的路径</param>
public void BinarySerialize<T>(T t, string path) where T : class
{
try
{
//string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, t);
}
catch (Exception ex)
{
Program.Log.Error($"Binary泛型序列化错误信息:{ex.ToString()}");
}
} /// <summary>
/// Binary泛型的反序列化
/// </summary>
/// <typeparam name="T">泛型类型</typeparam>
/// <param name="path">反序列化的序列化文件路径</param>
/// <returns>泛型对象</returns>
public T BinaryDeserialize<T>(string path) where T : class
{
T t = null;
try
{
//string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
using MemoryStream fs = new MemoryStream(File.ReadAllBytes(path));
BinaryFormatter bf = new BinaryFormatter();
if (bf.Deserialize(fs) is T a)
{
t = a;
}
}
catch (Exception ex)
{
Program.Log.Error($"Binary泛型的反序列化错误信息:{ex.ToString()}");
}
return t;
}
}
}
运行程序报错,错误信息是无法对泛型进行序列化,
第一种解决方式:Soap序列化无法对泛型List<T>进行序列化,解决方法1 :使用[OnSerializing]特性解决泛型List<T>序列化,修改Team为下面代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks; namespace SupremeConsole
{
[Serializable]
public class Team
{
#region 初始定义,使用Soap序列化PlayerList会报错,因为Soap序列化无法对泛型List<T>进行序列化,解决方法如下
///// <summary>
///// 队名
///// </summary>
//public string TName { get; set; } ///// <summary>
///// 选手
///// </summary>
//public List<Person> PlayerList = new List<Person>();
#endregion #region Soap序列化无法对泛型List<T>进行序列化,解决方法1 :使用[OnSerializing]特性解决泛型List<T>序列化
/// <summary>
/// 队名
/// </summary>
public string TName { get; set; } Person[] _PlayerArr; /// <summary>
/// 选手
/// </summary>
[NonSerialized] public List<Person> PlayerList = new List<Person>(); [OnSerializing]
public void SetPlayer(StreamingContext sc)
{
_PlayerArr = PlayerList.ToArray();
} [OnDeserialized]
public void SetPlayered(StreamingContext sc)
{
_PlayerArr = null;
} [OnDeserializing]
public void GetPlayer(StreamingContext sc)
{
PlayerList = new List<Person>(_PlayerArr);
} #endregion
}
}
在运行,可以序列化,但是反序列化的时候报错,集合为空错误,那么我们使用第二中解决方法,即实现ISerializable接口,
ISerializable接口中有GetObjectData(SerializationInfo info, StreamingContext context),序列化的时候会调用该方法,可以操作参数SerializationInfo ,SerializationInfo 是一个a name-value dictionary,
反序列化的时候,可以使用构造函数,构造函数的参数和GetObjectData的参数一样,即构造函数(SerializationInfo info, StreamingContext context)。
第二种解决方式:实现ISerializable接口对泛型List<T>进行序列化,修改Team为下面代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks; namespace SupremeConsole
{
[Serializable]
public class Team : ISerializable
{
/// <summary>
/// 队名
/// </summary>
public string TName { get; set; } /// <summary>
/// 选手
/// </summary>
public List<Person> PlayerList = new List<Person>(); /// <summary>
/// 序列化的时候会自动调用,使用virtual标记,示方便继承自类的使用
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("TName", TName);
info.AddValue("PlayerList", PlayerList);
} public Team()
{ } /// <summary>
/// 反序了列化的时候自动调用,使用protected标记,示方便继承自类的使用
/// </summary>
protected Team(SerializationInfo info, StreamingContext context)
{
TName = info.GetString("TName");
PlayerList = (List<Person>)info.GetValue("PlayerList",typeof(List<Person>));
}
}
}
再运行程序,可以看到序列化和反序列化都可以了。
其实,Binary与Soap无法对泛型List<T>进行序列化的解决方案,无非就是使用[OnSerializing]特性和实现ISerializable接口,
C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案的更多相关文章
- 初识序列化和反序列化,使用BinaryFormatter类、ISerializable接口、XmlSerializer类进行序列化和反序列化
序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程.对象一旦被序列化,就可以把对象状态保存到硬盘的某个位置,甚至还可以通过网络发送给另外一台机器上运行的进程.本篇主要包括: ● 使用 ...
- fastjson序列化和反序列化报com.alibaba.fastjson.JSONException: autoType is not support异常问题,解决方案整合
1.问题起因 2017年3月15日,fastjson官方发布安全升级公告,该公告介绍fastjson在1.2.24及之前的版本存在代码执行漏洞,当恶意攻击者提交一个精心构造的序列化数据到服务端时,由于 ...
- .NET Core 对象到字节数组的序列化和反序列化
.NET Core中利用MemoryStream和BinaryFormatter可以实现对象到字节数组的序列化和反序列化: 定义ObjectSerializer类,实现对象到字节数组的序列化和反序列化 ...
- 在C#中,Json的序列化和反序列化的几种方式总结
在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...
- 第一章 JacksonUtil 序列化与反序列化属性总结
1.json-lib与Jackson 关于json-lib与Jackson对比总结如下: 1).性能方面,Jackson的处理能力高出Json-lib10倍左右. 2).json-lib已经停止更新, ...
- php中序列化与反序列化在utf8和gbk编码中测试
在php中如果我们统一编码是没有什么问题了,但是很多朋友会发现一个问题就是utf8和gbk编码中返回的值会有所区别: php 在utf8和gbk编码下使用serialize和unserialize互相 ...
- Java基础18:Java序列化与反序列化
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- JAVA序列化和反序列化XML
package com.lss.utils; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.Bu ...
- Python开发之序列化与反序列化:pickle、json模块使用详解
1 引言 在日常开发中,所有的对象都是存储在内存当中,尤其是像python这样的坚持一切接对象的高级程序设计语言,一旦关机,在写在内存中的数据都将不复存在.另一方面,存储在内存够中的对象由于编程语言. ...
随机推荐
- react 爬坑记录
1.父子组件优化其一发生render条件:数据改变(state或者props改变),有时子组件会过多render.这时可在子组件里面的生命周期钩子里执行 shouldComponentUpdate(n ...
- tensorflow提示:No module named ''tensorflow.python.eager".
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_27921205/articl ...
- 【JMeter】压力测试工具的概览与使用
软件工程综合实践第五次个人作业 作业要求:在软件测试章节中,我们介绍了不少VSTS的软件测试工具,请使用一些其他平台上的测试工具,并写博客介绍如何在你的项目中具体使用. 前言: 第一次看到这个作业 ...
- AI的自学题库-竞赛-基础知识
阿里云(天池): https://tianchi.aliyun.com/course?spm=5176.12281897.0.0.209439a9UwObn3 天池竞赛:https://tianchi ...
- windows下端口占用解决办法,解决命令
1.netstat -aon|findstr "8183" 可以看到listener 对应的端口id 2.taskkill /pid {查询出来对应的id值} /f
- 网络空间安全基础篇(1)----nmap的使用
nmap工具通俗一点说,就是利用nmap工具来对靶机的所有端口及其开启的服务进行扫描,以便于黑客入侵靶机时,知道用什么漏洞去攻击. nmap常用的命令集(标为红色的一般为常用参数): sV 扫描版本O ...
- python的模块放在哪里
python程序中使用 import XXX 时,python解析器会在当前目录.已安装和第三方模块中搜索 xxx,如果都搜索不到就会报错. 使用sys.path.append()方法可以临时添加搜索 ...
- PAT 乙级 1005.继续(3n+1)猜想 C++/Java
1005 继续(3n+1)猜想 (25 分) 题目来源 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记 ...
- 2016年的EK工具
什么是Exploit Kit? 预打包了安装程序.控制面板.恶意代码以及相当数量的攻击工具.通常基于PHP的一个软件. Exploit Kit经济体制 价格在成百上千美元: 可以按日/周/月来付租金: ...
- 201671010436 王雪刚 实验十四 团队项目评审&课程学习总结
一:实验名称:团队项目评审&课程学习总结 二:实验目的与要求 (1)掌握软件项目评审会流程: (2)反思总结课程学习内容. 三:实验步骤 任务一:按照团队项目结对评审名单,由项目组扮演乙方,结 ...