【.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 ...
随机推荐
- 在PowerShell中使用curl(Invoke-WebRequest)
前言 习惯了windows的界面模式就很难转去命令行,甚至以命令行发家的git也涌现出各种界面tool.然而命令行真的会比界面快的多,如果你是一个码农. situation:接到需求分析bug,需要访 ...
- ASP.NET是如何在IIS下工作的
ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化. IIS6(IIS7的经典模式)与IIS7的集成模式的不同 IIS6 ...
- ABP框架 - Swagger UI 集成
文档目录 本节内容: 简介 Asp.net Core 安装 安装Nuget包 配置 测试 Asp.net 5.x 安装 安装Nuget包 配置 测试 简介 来自它的网页:“...使用一个Swagger ...
- 调用AJAX做登陆和注册
先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...
- Matlab 高脚杯模型切片
前言:此文为去年我替人做的一个课题,觉得比较简洁,图形也比较美观,因此放在博文里 数据源我放到了百度云盘高脚杯数据源 有兴趣的可以下载数据,跑程序试一下.也可以单独看看代码,看下实现过程. 主函数 % ...
- java设计模式之--单例模式
前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...
- 自己来实现一个简易的OCR
来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...
- Hibernate中事务声明
Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...
- python 数据类型 ---文件一
1.文件的操作流程: 打开(open), 操作(read,write), 关闭(close) 下面分别用三种方式打开文件,r,w,a 模式 . "a"模式将不会覆盖原来的文件内容, ...
- 登录(ajax提交数据和后台校验)
1.前台ajax数据提交 <form id="login_form" action="" method="POST"> < ...