【.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 ...
随机推荐
- Key/Value之王Memcached初探:二、Memcached在.Net中的基本操作
一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...
- C语言 · 阶乘计算 · 基础练习
问题描述 输入一个正整数n,输出n!的值. 其中n!=1*2*3*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法.使用一个数组A来表示一个大整数a,A[0]表 ...
- ASP.NET Web API 跨域访问(CORS)
一.客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignatu ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- JDBC简介
jdbc连接数据库的四个对象 DriverManager 驱动类 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 ...
- 【JQ基础】DOM操作
内部插入:append() //向每个匹配的元素内部追加内容,可包含 HTML 标签 $(selector).append(function(index,html)) /*•index - 可选.接收 ...
- Android中ListView实现图文并列并且自定义分割线(完善仿微信APP)
昨天的(今天凌晨)的博文<Android中Fragment和ViewPager那点事儿>中,我们通过使用Fragment和ViewPager模仿实现了微信的布局框架.今天我们来通过使用Li ...
- iOS 10 跳转系统设置
苦心人天不负, 为了项目终于把 iOS 10 跳转系统设置的方法给搞定了, 很欣慰. http://www.cnblogs.com/lurenq/p/6189580.html iOS 10 跳转系统设 ...
- 在MySQL数据库中创建一个完整的表
1.登陆成功后,首先进入某一个数据库 (不是指数据库服务器) use t1; //t1是数据库名 如图所示: 2.在此数据库中建立数据库表 2.1 先建立表结构(可以理解为表的列名,也就是字段名)在实 ...