C# 知识回顾 -  序列化

【博主】反骨仔    【原文地址】http://www.cnblogs.com/liqingwen/p/5902005.html

目录

一、序列化的含义

  序列化 (Serialization)将对象的状态信息处理为字节流,以便于存储或传输到内存、数据库或文件的一个过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区,主要目的是保存对象的状态。便于日后从该状态中进行还原,创建新的对象,这个过程又称为反序列化。

 

1.1 序列化的工作方式

图1.1-1

 
  对象被序列化为字节流(包括数据、对象的类型信息:如版本、区域性和程序集名称) --> 存储到 DB、IO 等地方。
 

1.2 用于序列化

  我们在数据交换的时候常进行序列化保存对象的数据信息,在需要使用它的时候再进行反序列化重新读取对象的信息并进行校验和存储的一些工作。常用于 Web 间传递数据,跨域传递,ASP .NET 后台代码往前端传递数据(js 进行解析处理)。
 

1.3 使对象可序列化

  进行序列化的操作,需要:一个带序列化的对象,一个是包含序列化对象的流和一个序列化器(Formatter)。
  我们进行编写的类中,默认会给类加上 SerializableAttribute 特性的,当然你也可以使用显式的方式进行添加。当你打算对一个对象进行序列化时,如果它不包含 SerializableAttribute,将会引发异常。在某些时候,我们可能不希望类中的某些字段或属性进行序列化操作,你可以在该字段或属性上使用 NonSerializedAttribute ,以告诉序列化器不对它们进行序列化操作。
 
  【备注】如果已序列化的类中包含了其他类对象的引用,而这些类又恰巧也有 SerializableAttribute,那么它们也会被进行序列化。
  【备注】序列化的关键字特性:SerializableAttributeNonSerializedAttribute

  这里介绍一种常见的序列化和一种不常见的序列化:

  (1)二进制序列化:使用二进制编码来生成精简的序列化,会序列化所有成员,并提高性能。常用于存储和 socket 传输。

  (2)XML 序列化:可读性更高,也就表示有更高的灵活性,操作的便利性。可用 XmlSerializer 进行序列化操作。

 
 

二、通过序列化保存对象数据

  这里使用 demo 进行简单演示如何对对象进行序列化和反序列化操作。

2.1 使用序列化保存对象

     [Serializable]  //将类标记为可序列化
public class Coupon : INotifyPropertyChanged
{
public decimal Amount { get; set; } public float InterestRate { get; set; } public int Term { get; set; } private string _name; public string Name
{
get { return _name; }
set
{
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Customer"));
}
} [field: NonSerialized()] //将可序列化的类中的某字段标记为不被序列化
public event PropertyChangedEventHandler PropertyChanged; public Coupon(decimal amount, float interestRate, int term, string name)
{
Amount = amount;
InterestRate = interestRate;
Term = term;
_name = name;
}
}

Coupon.cs

         static void Main(string[] args)
{
const string fileName = @"demo1.txt";
var coupon = new Coupon(, 0.2f, , "反骨仔"); using (var stream = File.Create(fileName))
{
var deserializer = new BinaryFormatter();  //二进制格式序列化器
deserializer.Serialize(stream, coupon);  //序列化对象到文件中
}
}

图2-1

  现在尝试反序列化,看看与之前 Coupon 对象的值是否一致。

         static void Main(string[] args)
{
const string fileName = @"demo1.txt";
//var coupon = new Coupon(10000, 0.2f, 1, "反骨仔"); //判断该文件是否存在
if (!File.Exists(fileName))
{
return;
} using (var stream = File.OpenRead(fileName))
{
var deserializer = new BinaryFormatter(); //二进制序列化器
var coupon = deserializer.Deserialize(stream) as Coupon; //反序列化 if (coupon == null)
{
return;
} Console.WriteLine($"{nameof(Coupon)}:");
Console.WriteLine($" {nameof(coupon.Amount)}: {coupon.Amount}");
Console.WriteLine($" {nameof(coupon.InterestRate)}: {coupon.InterestRate}%");
Console.WriteLine($" {nameof(coupon.Term)}: {coupon.Term}");
Console.WriteLine($" {nameof(coupon.Name)}: {coupon.Name}");
} Console.Read();
}

图2-2

2.2 使用 SOAP 格式保存对象

         static void Main(string[] args)
{
const string fileName = @"demo1.txt";
var coupon = new Coupon(, 0.2f, , "反骨仔"); using (var stream = File.Create(fileName))
{
var deserializer = new SoapFormatter(); //Soap 格式化器
deserializer.Serialize(stream, coupon); //序列化
}
}

图2-3

  反序列化时也采用 SoapFormatter 即可,结果同图2-2。

                var deserializer = new SoapFormatter();   //Soap 格式化器
var coupon = deserializer.Deserialize(stream) as Coupon; //反序列化

  【注意】不应将这些格式用于敏感数据,如密码或信用卡信息。

  【备注】二进制格式对于大多数 Windows 应用程序均适用。对于以前来说,使用 Web 应用程序或者是 Web 服务,建议使用 SOAP 的 XML 进行传输。而现在,当然是使用大众化的 json 格式进行传输啦。

  同样,也可以通过 XmlSerializer 将对象序列化保存在 XML 文件。我们可以根据需求选择合适的序列化器,操作基本是一样的。

众说纷纭

  @hi丶小时候 使用 SerializableAttribute 特性时,是不建议使用自动属性的,序列化后的字段都是多出 k_BackingField<> 17个字符,如果对象很大会浪费一部分流量,建议使用 DataContractAttribute 和 DataMemberAttribute

  @梁逸晨 除非对方系统强制要求 SOAP 才能通信,否则该人人抵制这么反人类的东西,建议楼主 JSON 或 Protobuf


【参考】https://msdn.microsoft.com/zh-cn/subscriptions/ms233843(v=vs.100).aspx

【参考】微软官方文档

[C#] C# 知识回顾 - 序列化的更多相关文章

  1. [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?

    你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...

  2. [C#] C# 知识回顾 - 学会处理异常

    学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...

  3. [C#] C# 知识回顾 - 学会使用异常

    学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...

  4. [C#] C# 知识回顾 - 异常介绍

    异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...

  5. [.NET] C# 知识回顾 - Event 事件

    C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...

  6. [.NET] C# 知识回顾 - 事件入门

    C# 知识回顾 - 事件入门 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6057301.html 序 之前通过<C# 知识回顾 - 委托 de ...

  7. [.NET] C# 知识回顾 - 委托 delegate (续)

    C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...

  8. [C#] C# 知识回顾 - 委托 delegate

    C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...

  9. C# 知识回顾 - 装箱与拆箱

    装箱与拆箱 目录 生活中的装箱与拆箱 C# 的装箱与拆箱 值类型和引用类型 装箱 拆箱 生活中的装箱与拆箱    我们习惯了在网上购物,这次你想买本编程书 -- <C 语言从入门到放弃> ...

随机推荐

  1. C# 利用性能计数器监控网络状态

    本例是利用C#中的性能计数器(PerformanceCounter)监控网络的状态.并能够直观的展现出来 涉及到的知识点: PerformanceCounter,表示 Windows NT 性能计数器 ...

  2. MyEclipse生成注册码

    今天正在使用的MyEclipse出现了使用过期,在网上发现一个可以生成注册码的程序,现在分享给各位. /** * myEclipse生成注册码 * 点击顶部:MyEclipse --> subs ...

  3. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  4. 开发者接入 基本配置 服务器配置 out.aspx

    页面代码: 前段为默认的,什么都不用写,后台如下: 即可 来自为知笔记(Wiz)

  5. Android 几种消息推送方案总结

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6241354.html 首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量: 现 ...

  6. php实现的分页类

    php分页类文件: <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 pr ...

  7. Linux之搭建自己的根文件系统

    Hi!大家好,我是CrazyCatJack.又和大家见面了.今天给大家带来的是构建Linux下的根文件系统.希望大家看过之后都能构建出符合自己需求的根文件系统^_^ 1.内容概述 1.构造过程 今天给 ...

  8. 基于SignalR的消息推送与二维码描登录实现

    1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...

  9. ASP.NET MVC5----常见的数据注解和验证

    只要一直走,慢点又何妨. 在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法. 什么是验证,数据注解 验证 从全局来看,发现逻辑仅是整个验证的很小的一部 ...

  10. 在DevExpress程序中使用GridView直接录入数据的时候,增加列表选择的功能

    在我上篇随笔<在DevExpress程序中使用Winform分页控件直接录入数据并保存>中介绍了在GridView以及在其封装的分页控件上做数据的直接录入的处理,介绍情况下数据的保存和校验 ...