【.net 深呼吸】序列化中的“引用保留”
假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据。
看看下面两个类。
[DataContract]
public class 帅哥
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public float Height { get; set; }
[DataMember]
public ContactInfo ContactData1 { get; set; }
[DataMember]
public ContactInfo ContactData2 { get; set; }
} [DataContract]
public class ContactInfo
{
[DataMember]
public string Phone { get; set; }
[DataMember]
public string Email { get; set; }
}
假设 ContactInfo 表示联系方式,帅哥有两个联系方式。
-------------------------------------------------------------
ContactInfo cinfo = new ContactInfo
{
Email = "big_pig@珊瑚虫.com",
Phone = ""
}; 帅哥 wg = new 帅哥
{
Name = "王小八",
Age = ,
Height = 1.414f,
ContactData1 = cinfo,
ContactData2 = cinfo
};
在上面代码中,帅哥实例的两种联系方式都引用了同一个 ContactInfo 对象。如果把该帅哥实例序列化。
DataContractSerializer szr = new DataContractSerializer(wg.GetType());
MemoryStream mstream = new MemoryStream();
szr.WriteObject(mstream, wg);
就会得到以下XML文档:
<帅哥 xmlns="http://schemas.datacontract.org/2004/07/SampleApp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Age></Age>
<ContactData1>
<Email>big_pig@珊瑚虫.com</Email>
<Phone></Phone>
</ContactData1>
<ContactData2>
<Email>big_pig@珊瑚虫.com</Email>
<Phone></Phone>
</ContactData2>
<Height>1.414</Height>
<Name>王小八</Name>
</帅哥>
从上面生成的XML文档可知,引用的尽管是同一个实例,但很显然,ContactInfo 的数据被写入了两次。
----------------------------------------------------------
那么,如果改为保留引用呢,看
DataContractSerializerSettings settings = new DataContractSerializerSettings();
settings.PreserveObjectReferences = true;
DataContractSerializer szr = new DataContractSerializer(wg.GetType(), settings);
MemoryStream mstream = new MemoryStream();
szr.WriteObject(mstream, wg);
将 PreserveObjectReferences 属性设置为 true,表示同一实例引用只写入一次。
修改后生成的XML文档如下:
<帅哥 z:Id="" xmlns="http://schemas.datacontract.org/2004/07/SampleApp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Age></Age>
<ContactData1 z:Id="">
<Email z:Id="">big_pig@珊瑚虫.com</Email>
<Phone z:Id=""></Phone>
</ContactData1>
<ContactData2 z:Ref="" i:nil="true" />
<Height>1.414</Height>
<Name z:Id="">王小八</Name>
</帅哥>
你看,这一回的 XML 是不是比刚才的要简短了?因为同一个 ContactInfo 实例只写入了一次,并且给其中一个引用分配一个 id,后面如果还用到,就直接使用对象的 id 就行了,这样避免了重复写入内容。
好了,今天分享的内容不能称得上是高大上,但老周觉得,是有价值的,希望对各位有用。
【.net 深呼吸】序列化中的“引用保留”的更多相关文章
- EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json
1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出 ...
- 浅谈Java中的引用
在Java语言中,引用是指,某一个数据,代表的是另外一块内存的的起始地址,那么我们就称这个数据为引用. 在JVM中,GC回收的大致准则,是认定如果不能从根节点,根据引用的不断传递,最终指向到一块内存区 ...
- 解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json
1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2: ...
- WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用
原文:WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经> ...
- vs LNK2019 无法解析的外部符号 ***,该符号在函数 WinMain 中被引用
一般链接错误都是因为包含头文件与lib库不匹配(无导出函数.lib库的release debug版本混乱.库引用的优先级.编译器设置mt/mtd等等)造成的. 错误 LNK2019 无法解 ...
- Android ImageView 不显示JPEG图片 及 Android Studio中怎样引用图片资源
Android ImageView 不显示JPEG图片 今天在写一个小实例,ImageView在xml里面设置的是INVISIBLE,在代码里须要设置成setVisibility(View.VISIB ...
- JVM:Java中的引用
JVM:Java中的引用 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 在原来的时候,我们谈到一个类的实例化 Person p = new Person() 在 ...
- php中关于引用(&)详解
php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...
- error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 Debug ...
随机推荐
- 基于DDD的现代ASP.NET开发框架--ABP系列文章总目录
ABP相关岗位招聘:给热爱.NET新技术和ABP框架的朋友带来一个高薪的工作机会 ABP交流会录像视频:ABP架构设计交流群-7月18日上海线下交流会的内容分享(有高清录像视频的链接) 代码自动生成: ...
- Web大前端时代之:HTML5+CSS3入门系列
准备来一波新技术,待续.... Old: 联系源码:https://github.com/dunitian/LoTHTML5 文档下载:https://github.com/dunitian/LoTD ...
- mybatis_映射查询
一.一对一映射查询: 第一种方式(手动映射):借助resultType属性,定义专门的pojo类作为输出类型,其中该po类中封装了查询结果集中所有的字段.此方法较为简单,企业中使用普遍. <!- ...
- Oracle碎碎念~2
1. 如何查看表的列名及类型 SQL> select column_name,data_type,data_length from all_tab_columns where owner='SC ...
- vue入门学习(基础篇)
vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...
- MongoDB系列(二):C#应用
前言 上一篇文章<MongoDB系列(一):简介及安装>已经介绍了MongoDB以及其在window环境下的安装,这篇文章主要讲讲如何用C#来与MongoDB进行通讯.再次强调一下,我使用 ...
- 深入Java虚拟机--判断对象存活状态
程序计数器,虚拟机栈和本地方法栈 首先我们先来看下垃圾回收中不会管理到的内存区域,在Java虚拟机的运行时数据区我们可以看到,程序计数器,虚拟机栈,本地方法栈这三个地方是比较特别的.这个三个部分的特点 ...
- JavaScript基础知识总结(二)
JavaScript语法 二.数据类型 程序把这些量.值分为几大类,每一类分别叫什么名称,有什么特点,就叫数据类型. 1.字符串(string) 字符串由零个或多个字符构成,字符包括字母,数字,标点符 ...
- fir.im Weekly - 关于 iOS10 适配、开发、推送的一切
"小程序"来了,微信变成名副其实的 Web OS,新一轮的Web App 与Native App争论四起.程序员对新技术永远保持灵敏的嗅觉和旺盛的好奇心,@李锦发整理了微信小程序资 ...
- 基于Composer Player 模型加载和相关属性设置
主要是基于达索软件Composer Player.的基础上做些二次开发. public class ComposerToolBarSetting { public bool AntiAliasingO ...