博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C#] C# 知识回顾 - 序列化
阅读量:5262 次
发布时间:2019-06-14

本文共 4515 字,大约阅读时间需要 15 分钟。

C# 知识回顾 -  序列化

 【博主】反骨仔    【原文地址】

目录

 

一、序列化的含义

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

 

1.1 序列化的工作方式

图1.1-1

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

1.2 用于序列化

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

1.3 使对象可序列化

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

 

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

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

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

 
 

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

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

 

2.1 使用序列化保存对象

1     [Serializable]  //将类标记为可序列化 2     public class Coupon : INotifyPropertyChanged 3     { 4         public decimal Amount { get; set; } 5  6         public float InterestRate { get; set; } 7  8         public int Term { get; set; } 9 10         private string _name;11 12         public string Name13         {14             get { return _name; }15             set16             {17                 _name = value;18                 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Customer"));19             }20         }21 22         [field: NonSerialized()]    //将可序列化的类中的某字段标记为不被序列化23         public event PropertyChangedEventHandler PropertyChanged;24 25         public Coupon(decimal amount, float interestRate, int term, string name)26         {27             Amount = amount;28             InterestRate = interestRate;29             Term = term;30             _name = name;31         }32     }
Coupon.cs
1         static void Main(string[] args) 2         { 3             const string fileName = @"demo1.txt"; 4             var coupon = new Coupon(10000, 0.2f, 1, "反骨仔"); 5  6             using (var stream = File.Create(fileName)) 7             { 8                 var deserializer = new BinaryFormatter();  //二进制格式序列化器 9                 deserializer.Serialize(stream, coupon);  //序列化对象到文件中10             }11         }

图2-1 

 

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

1         static void Main(string[] args) 2         { 3             const string fileName = @"demo1.txt"; 4             //var coupon = new Coupon(10000, 0.2f, 1, "反骨仔"); 5  6             //判断该文件是否存在 7             if (!File.Exists(fileName)) 8             { 9                 return;10             }11 12             using (var stream = File.OpenRead(fileName))13             {14                 var deserializer = new BinaryFormatter();   //二进制序列化器15                 var coupon = deserializer.Deserialize(stream) as Coupon;    //反序列化16 17                 if (coupon == null)18                 {19                     return;20                 }21 22                 Console.WriteLine($"{nameof(Coupon)}:");23                 Console.WriteLine($"    {nameof(coupon.Amount)}: {coupon.Amount}");24                 Console.WriteLine($"    {nameof(coupon.InterestRate)}: {coupon.InterestRate}%");25                 Console.WriteLine($"    {nameof(coupon.Term)}: {coupon.Term}");26                 Console.WriteLine($"    {nameof(coupon.Name)}: {coupon.Name}");27             }28 29             Console.Read();30         }

图2-2

 

2.2 使用 SOAP 格式保存对象

1         static void Main(string[] args) 2         { 3             const string fileName = @"demo1.txt"; 4             var coupon = new Coupon(10000, 0.2f, 1, "反骨仔"); 5  6             using (var stream = File.Create(fileName)) 7             { 8                 var deserializer = new SoapFormatter(); //Soap 格式化器 9                 deserializer.Serialize(stream, coupon); //序列化10             }11         }

图2-3

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

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

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

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

 

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

 

众说纷纭

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

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

 

 


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

【参考】微软官方文档

 

转载于:https://www.cnblogs.com/liqingwen/p/5902005.html

你可能感兴趣的文章
storyboard-UITabBar选中时颜色
查看>>
【BZOJ4373】算术天才⑨与等差数列 线段树+set
查看>>
【BZOJ3774】最优选择 最小割
查看>>
JavaScript创建对象的7种方式及比较
查看>>
Sybase 数据库新增用户,赋权
查看>>
mingw64环境搭建
查看>>
ffmpeg文档16-音频编码器
查看>>
双曲抛物面
查看>>
深度神经网络:特点、问题及解决
查看>>
极值点、驻点、鞍点、拐点
查看>>
句子的理解
查看>>
prim算法
查看>>
sql语句的优先级
查看>>
css 滚动条样式
查看>>
jQuery 中 attr 和 prop 方法的区别
查看>>
1.1 java变量及数据类型
查看>>
Oracle数据库---PLSQL
查看>>
bash中变量的种类及其用法
查看>>
Linux-正则表达式的POSIX规范及流派
查看>>
PHP-PHP-FPM的max_children一些误区
查看>>