假设 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. 在PowerShell中使用curl(Invoke-WebRequest)

    前言 习惯了windows的界面模式就很难转去命令行,甚至以命令行发家的git也涌现出各种界面tool.然而命令行真的会比界面快的多,如果你是一个码农. situation:接到需求分析bug,需要访 ...

  2. ASP.NET是如何在IIS下工作的

    ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化. IIS6(IIS7的经典模式)与IIS7的集成模式的不同 IIS6 ...

  3. ABP框架 - Swagger UI 集成

    文档目录 本节内容: 简介 Asp.net Core 安装 安装Nuget包 配置 测试 Asp.net 5.x 安装 安装Nuget包 配置 测试 简介 来自它的网页:“...使用一个Swagger ...

  4. 调用AJAX做登陆和注册

    先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...

  5. Matlab 高脚杯模型切片

    前言:此文为去年我替人做的一个课题,觉得比较简洁,图形也比较美观,因此放在博文里 数据源我放到了百度云盘高脚杯数据源 有兴趣的可以下载数据,跑程序试一下.也可以单独看看代码,看下实现过程. 主函数 % ...

  6. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...

  7. 自己来实现一个简易的OCR

    来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...

  8. Hibernate中事务声明

    Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...

  9. python 数据类型 ---文件一

    1.文件的操作流程: 打开(open), 操作(read,write), 关闭(close) 下面分别用三种方式打开文件,r,w,a 模式 . "a"模式将不会覆盖原来的文件内容, ...

  10. 登录(ajax提交数据和后台校验)

    1.前台ajax数据提交 <form id="login_form" action="" method="POST"> < ...