当前位置: 首页 > 编程日记 > 正文

不同命名空间的对象二进制反序列化问题

本质上说,这并不是二进制序列化的问题,甚至不关序列化的问题。

你想要的是在两个内部结构一致但在不同命名空间(甚至不同项目)的同名类间做类型转换。

这个问题很常见,因为实际工作中经常会有此类需求,但是我们又不可能手动的把每个字段的值都抄来抄去。

解决此问题的方法很多,但都逃不开一个关键思想:A不知道B的存在,B不知道A的存在,那么我就找出一个C,只要A和B都能以C的形式表示,那么转换就不是问题。这里的C是概念上的一个标准,用于当做A和B转换的桥梁。

普遍的解决方法:

  1. 如一楼所说,XmlSerializer序列化器能够将一个可Xml序列化的类A的“内容”部分抽取出来序列化成Xml片段,也能够将其反序列化为一个符合该Xml“格式”的类B。代码如下。

    序列化端:

1
2
3
4
5
6
7
8
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(classA));
System.IO.Stream stream = new System.IO.FileStream(@"c:\tmp.txt",System.IO.FileMode.OpenOrCreate);
xs.Serialize(stream, new classA { i = 10, s = "hello" });
stream.Dispose();
反序列化端:
 System.Xml.Serialization.XmlSerializer xsb = new System.Xml.Serialization.XmlSerializer(typeof(classA));
 classA b = (classA)xsb.Deserialize(new System.IO.FileStream(@"c:\tmp.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read));

打开c:\tmp.txt,我们可以看到中间传输的内容是

1
2
3
4
5
<?xml version="1.0"?>
<classA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <i>10</i>
  <s>hello</s>
</classA>

这表明了传输的内容只关注类名和共有属性/字段。所以在反序列化端,只要我们有同样结构的同名类classA,是可以直接从Xml流进行转换的。当然使用内存流、字节流等都是可以的。这里一定要切记三点:同名同结构(指共有字段/属性部分)的两个类,以及只能序列化公有字段和属性,两个类都必须有默认构造方法。

Xml序列化的优点在于只序列化必要部分且消耗较少,常用于序列化DataTable等结构。

2.第二种方法是使用接口。也许你的两个类分处不同的命名空间或者不同项目,但是只要都能访问到同一interface,那么我们可以稍微费点功夫写一个两个都“认识”的接口,通过接口来转换对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface dataInterface
    {
        int i{get;set;}
        string s{get;set;}
    }
    [Serializable]
    public class classA : dataInterface
    {
        public int i{get;set;}
        public string s{get;set;}
    }
    [Serializable]
    public class classB : dataInterface
    {
        public int i{get;set}
        public string s{get;set;}
    }

如此,不管classA和classB在哪里,只要你认得dataInterface,那么就可以用其来传输、访问和转换。传输的过程相比xml序列化就灵活多了,你可以使用socket、文件、消息、甚至共享内存等等手段来传输,序列化也可以使用万能的二进制序列化,因为你传出和接受的,都是dataInterface对象而已。

序列化端(二进制序列化+文件传输举例):

1
2
3
4
 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            System.IO.FileStream fs = new System.IO.FileStream(@"c:\tmp", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
            formatter.Serialize(fs, (new classA { i = 10, s = "hello" }));
            fs.Dispose();

反序列化:

1
dataInterface data = (dataInterface)formatter.Deserialize(new System.IO.FileStream(@"c:\tmp", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read));

此方法优缺点显而易见。优点是无视两个类的位置、无需同名同结构,缺点是有额外工作(写接口)外加反序列化后只能得到接口不能得到classB。额外注意,上例中使用的二进制序列化需要在类上标记[Serializable]。

除此之外还有很多种方法可以做跨域类型转换,但并不常用,这里就不再敖述了。

转载于:https://www.cnblogs.com/yy1234/p/8405556.html

相关文章:

对大文件的断点续传

注&#xff1a;#import "YGFileDownloader.h"是对NSURLConnection的简单封装 #import "YGResumeDownloadViewController.h" #import "NSStringutil.h"#import "YGFileDownloader.h"#define URL "http://dlsw.baidu.com/sw-searc…

bootstrap modal 弹出效果

window.showMsg function (msg) {//显示悬浮窗$("#autoCloseModal").modal("show")//设置文本内容$("#autoCloseModal #autoCloseModalBody").html("")$("#autoCloseModal #autoCloseModalBody").html(msg);//两秒后消失se…

68-95-99规则–以普通英语解释正态分布

Meet Mason. Hes an average American 40-year-old: 5 foot 10 inches tall and earning $47,000 per year before tax.认识梅森。 他平均年龄40岁&#xff0c;身高5英尺10英寸&#xff0c;每年税前收入$ 47,000。 How often would you expect to meet someone who earns 10x …

Uva 10048 - Audiophobia (Floyd变形)

题目链接 https://vjudge.net/problem/UVA-10048 【题意】 输入一个C个点&#xff0c;S个边&#xff08;C<100,S<1000&#xff09;的无向图&#xff0c;边权表示该路径上的噪声值&#xff0c;当你从某点出发到另外一点时希望路上经过的最大噪声值最小&#xff0c;输入一…

ubuntu联网经常掉线的解决方法

打开电脑&#xff0c;发现联网的图标没有连接上&#xff0c;想手动点击连接上&#xff0c;却发现选项是灰色&#xff08;不可选&#xff09; 或者是图标显示已经连接上了&#xff0c;但浏览器就是无法上网&#xff0c;也ping不通 此时打开终端输入 sudo /etc/init.d/network-ma…

JSON和XML

JSONJSON(JavaScript Object Notation)一种轻量级的数据交换格式&#xff0c;具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。JSON采用兼容性很高的、完全独立于语言文本格式&#xff0c;同时也具备类似于C语言的习惯(包括C, C, C#, Java, JavaScript, Pe…

deno使用rust_如何在Deno和Oak中使用MySQL

deno使用rustI recently wrote about how to make a Todo API in Deno Oak (without using a database). You can find the repo under chapter_1:oak on GitHub. 我最近写了关于如何在Deno Oak(不使用数据库)中制作Todo API的文章 。 您可以在GitHub上的Chapter_1&#xff1…

Zookeeper 安装和配置

Zookeeper 安装和配置01 ZooKeeper的安装与部署02转载于:https://www.cnblogs.com/hfultrastrong/p/8414587.html

iOS中的各种手势

/**基类UIGestureRecognizerUITapGestureRecognizer Tap 点击UIPanGestureRecognizer Pan (慢速滑动&#xff0c;拖移)UILongPressGestureRecognizer LongPress (长按)UIPinchGestureRecognizer Pinch &#xff08;捏合&#xff0c;两手指往内或外拨动&…

Nginx问题定位之监控进程异常退出

nginx在运行过程中是否稳定&#xff0c;是否有异常退出过&#xff1f;这里总结几项平时会用到的小技巧。 1. 在error.log中查看是否有signal项&#xff0c;如果有&#xff0c;看看signal是多少。 比如&#xff0c;这是一个异常退出的情况&#xff1a; $grep signal error.log20…

k3应付系统初始化应付票据_在家工作时应付无尽干扰的真实感觉

k3应付系统初始化应付票据Whether or not you have worked remotely before, you’ve likely never had to share your “home office” with your partner and two children. 无论您以前是否在远程工作&#xff0c;您都可能从未与伴侣和两个孩子共享“家庭办公室”。 Before …

WinForm绘制带有升序、降序的柱形图

WinForm绘制带有升序、降序的柱形图 private void HuiZhiTu( string strPaiXu){//初始数据int[] nums { 150, 89, 200, 60, 70, 90 };if (strPaiXu "升序"){//冒泡排序for (int i 0; i < nums.Length; i){for (int j 0; j < nums.Length-1; j){if (nums[i]…

更轻量的 View Controllers

原文链接&#xff1a;http://objccn.io/issue-1-1/ View controllers 通常是 iOS 项目中最大的文件&#xff0c;并且它们包含了许多不必要的代码。所以 View controllers 中的代码几乎总是复用率最低的。我们将会看到给 view controllers 瘦身的技术&#xff0c;让代码变得可以…

Alpha阶段项目总结

一&#xff0c;设想和目标 1. 我们的软件要解决什么问题&#xff1f;是否定义得很清楚&#xff1f;是否对典型用户和典型场景有清晰的描述&#xff1f; 针对铁大校园&#xff0c;解决旧物堆积、资源浪费的问题。我们的定义很清楚&#xff0c;对于典型用户和场景有过清晰的描述。…

如何成为软件工程师的团队合作者

In my first software engineering role at an eCommerce brand, I often secretly worked on tasks outside of my core responsibilities. And many times I felt isolated from my teammates. 在电子商务品牌的第一个软件工程职位中&#xff0c;我经常秘密地从事核心职责以外…

HTML转义字符

转自地址&#xff1a;http://blog.csdn.net/wusuopubupt/article/details/8817826 by wusuopubupt No.文字表記10進表記16進表記文字 Comment001&quot;&#x22;""" quotation mark APL quote002&amp;&#x26;"&" ampersand003<&l…

制作模拟器和真机通用静态库

通常在项目中使用静态库的时候都会有两个版本&#xff0c;一个用于模拟器&#xff0c;一个用于真机&#xff0c;因为Mac和iPhone的CPU不同&#xff0c;才造成了这种情况。 为了模拟器与真机之间切换调试的方便&#xff0c;制作通用版本非常有必要。现在有两个版本的静态库libSQ…

使用静态URL片段 URL路由 精通ASP-NET-MVC-5-弗瑞曼

转载于:https://www.cnblogs.com/ganmk--jy/p/5570718.html

sql算术运算符_SQL运算符教程–按位,比较,算术和逻辑运算符查询示例

sql算术运算符At its core, the internet and all its applications are just data.互联网及其所有应用程序的核心只是数据。 Every email, tweet, selfie, bank transaction, and more is just data sitting in a database somewhere.每封电子邮件&#xff0c;推文&#xff0…

python 之socket 网络编程

socket通常也称作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一个通信链的句柄&#xff0c;应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 socket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&#xff0c…

(转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署

背景&#xff1a;最近项目组在开发本地缓存&#xff0c;其中用到了redis和ehcache&#xff0c;但是在使用注解过程中发现两者会出现冲突&#xff0c;这里给出解决两者冲突的具体方案。 spring-ehcache.xml配置&#xff1a; <?xml version"1.0" encoding"UTF…

终端SVN常用命令

svn help 帮助 svn checkout path 从服务器checkout文件到本地(path是服务器上的目录&#xff0c;简写svn co path) svn add file_name 往代码库添加新的文件 svn commit -m "xxx" 提交添加的文件&#xff0c;或者本地做的修改到服务器端(“xxx”内为提交说明…

程序员怎么赚更多的钱_自由职业技巧:如何感到更加自信和赚更多钱

程序员怎么赚更多的钱Over my 10 years as a freelance developer, many fellow freelancers have asked me for advice. How can they make freelancing work for them?在我作为自由开发者的10年中&#xff0c;许多自由职业者都向我寻求建议。 他们如何让他们从事自由职业&am…

RedHat 7.0及CentOS 7.0禁止Ping的三种方法

作者&#xff1a;荒原之梦原文链接&#xff1a;http://zhaokaifeng.com/?p538前言&#xff1a; “Ping”属于ICMP协议&#xff08;即“Internet控制报文协议”&#xff09;&#xff0c;而ICMP协议是TCP/IP协议的一个子协议&#xff0c;工作在网际层。ICMP协议主要用于传输网络…

关于sql 增删改

1.更改数据库的名称 --更改数据库的名称&#xff0c;逗号前面是之前的&#xff0c;后面是改成的名 sp_renamedb student,xuesheng 2.表中有数据的情况下再添加列、删除列 --后来添加列&#xff0c;只能默认可以为空值 altear table shuiguo add [int] varchar(10) --int加上中括…

使用version遇到的那些坑

公司代码管理使用的SVN, 所以就用到了SVN工具version 公司没给买正版的version, 遇到各种崩溃, 各种坑 1. 更新项目时遇到网络不稳定的情况, 更新失败, 项目中的某个文件就莫名其妙的被锁定了 !!! 如果只是更新一个文件还好说, unlock一下就好了,但是如果你是一个文件夹全部…

docker手册_Docker手册

docker手册The concept of containerization itself is pretty old, but the emergence of the Docker Engine in 2013 has made it much easier to containerize your applications. 容器化本身的概念还很老&#xff0c;但是Docker Engine在2013年的出现使容器化应用程序变得更…

MongoDB修改器的使用1

为什么要使用修改器&#xff1f; 通常我们只会修改文档的一部分&#xff0c;这时候更新整个文档就显得很麻烦&#xff0c;通常是通过原子性的更新修改器来完成。 1."$set"修改器 "$set"用来指定某个字段&#xff0c;如果不存在&#xff0c;则创建。这对部…

4GL之Non-SCROLLING CURSOR

在4gl中CURSOR可以说是每一个程序中都会有的&#xff0c;而CURSOR又分为三种SCROLLING CURSOR、Non-SCROLLING CURSOR、LOCKING CURSOR。 Non-SCROLLING CURSOR的聲明有兩種&#xff0c;一種是先定義好sql語句到一個變量里&#xff1a; DECLARE cursor名 CURSOR FROM 變量…

项目总结三--波纹视图

波纹视图的使用 代码在github&#xff1a;https://github.com/wyon0313/YGMoireAnimation