假设 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 深呼吸】序列化中的“引用保留”的更多相关文章

  1. EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

    1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出 ...

  2. 浅谈Java中的引用

    在Java语言中,引用是指,某一个数据,代表的是另外一块内存的的起始地址,那么我们就称这个数据为引用. 在JVM中,GC回收的大致准则,是认定如果不能从根节点,根据引用的不断传递,最终指向到一块内存区 ...

  3. 解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

    1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2: ...

  4. WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用

    原文:WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经> ...

  5. vs LNK2019 无法解析的外部符号 ***,该符号在函数 WinMain 中被引用

    一般链接错误都是因为包含头文件与lib库不匹配(无导出函数.lib库的release debug版本混乱.库引用的优先级.编译器设置mt/mtd等等)造成的. 错误    LNK2019    无法解 ...

  6. Android ImageView 不显示JPEG图片 及 Android Studio中怎样引用图片资源

    Android ImageView 不显示JPEG图片 今天在写一个小实例,ImageView在xml里面设置的是INVISIBLE,在代码里须要设置成setVisibility(View.VISIB ...

  7. JVM:Java中的引用

    JVM:Java中的引用 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 在原来的时候,我们谈到一个类的实例化 Person p = new Person() 在 ...

  8. php中关于引用(&)详解

    php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...

  9. error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用

    MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 Debug ...

随机推荐

  1. CSS 3学习——animation动画

    以下内容根据官方文档翻译以及自己的理解整理. 1.  介绍 本方案介绍动画(animations).通过动画,开发者可以将CSS属性值的变化指定为一个随时间变化的关键帧(keyframes)的集合.在 ...

  2. ASP.NET Core 折腾笔记一

    前言: 在ASP.NET Core 1.0时,曾折腾过一次,后因发现不了System.Data而停止. 更因VS2015提示过期Delete掉VS了,其实主要还是笔记本的硬盘空间吃紧. 快双十一了,本 ...

  3. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  4. 使用python抓取婚恋网用户数据并用决策树生成自己择偶观

    最近在看<机器学习实战>的时候萌生了一个想法,自己去网上爬一些数据按照书上的方法处理一下,不仅可以加深自己对书本的理解,顺便还可以在github拉拉人气.刚好在看决策树这一章,书里面的理论 ...

  5. 用scikit-learn学习BIRCH聚类

    在BIRCH聚类算法原理中,我们对BIRCH聚类算法的原理做了总结,本文就对scikit-learn中BIRCH算法的使用做一个总结. 1. scikit-learn之BIRCH类 在scikit-l ...

  6. Javascript实用方法二

    承接上一篇, Object keys object的keys方法能够获取一个给定对象的所有键(key/属性名)并以数组的形式返回.这个方法可以用于键的筛选.匹配等. var basket = { st ...

  7. angluarjs2项目生成内容合并到asp.net mvc4项目中一起发布

    应用场景 angular2(下文中标注位NG2)项目和.net mvc项目分别开发,前期采用跨域访问进行并行开发,后期只需要将NG2项目的生产版本合并到.net项目. NG2项目概述 ng2项目采用的 ...

  8. 推荐一个ASP.NET网站内容管理系统源码

    许多人都有各自的兴趣,如打球.踢毽子.看书.看电视.玩游戏等等....我近来迷上了猜灯谜,于是业余做了一个在线猜灯谜的网站:何问起谜语. 先出个谜语让你猜猜:不可缺一点(打一字).可以在线猜:http ...

  9. stringstream的基本用法

    原帖地址:https://zhidao.baidu.com/question/580048330.htmlstringstream是字符串流.它将流与存储在内存中的string对象绑定起来.在多种数据 ...

  10. BPM配置故事之案例6-条件可见与条件必填

    小明兴奋的告诉大毛自己独立解决了必填和水印问题,腹黑的大毛决定给小明出一个进阶问题刷一下存在感. 大毛:我再考考你,我把表单改成了这样(下图).怎么做到,预算状态为"预算内"时,不 ...