NET中的对象连串化,引用类型对象的深拷贝

c#中的对象大体分为值类型和引用类型,值类型大约包涵 int, string, struct等,引用类型差不离包含 自定义Class,object 等。

摘要:

C# Serializable

System.SerializableAttribute

串行化是指储存和取得磁盘文件、内部存储器或其余地方中的对象。在串行化时,全部的实例数据都保留到存款和储蓄介质上,在废除串行化时,对象会被苏醒,且不能够与其原实例分歧开来。

只需给类添加Serializable属性,就可以完成串行化实例的积极分子。

并行化是串行化的逆进度,数据从存款和储蓄介质中读取出来,并赋给类的实例变量。

例:

澳门葡京备用网址 1

 1 [Serializable]
 2 public class Person
 3 {
 4     public Person()
 5     {
 6     }
 7 
 8     public int Age;
 9     public int WeightInPounds;
10 }

澳门葡京备用网址 2

 

上面来看贰个小例子,首先要添加命名空间

using System.Runtime.Serialization.Formatters.Binary;

 

上边包车型地铁代码将对象Person进行系列化并储存到2个文件中

澳门葡京备用网址 3

 1 Person me = new Person();
 2 
 3 me.Age = 34;
 4 me.WeightInPounds = 200;
 5 
 6 Stream s = File.Open("Me.dat",FileMode.Create);
 7 
 8 BinaryFormatter bf = new BinaryFormatter();
 9 
10 bf.Serialize(s,me);
11 
12 s.Close();

澳门葡京备用网址 4

 

然后再举1个并行化的例证

澳门葡京备用网址 5

 1 Stream s = File.Open("Me.dat",FileMode.Open);
 2 
 3 BinaryFormatter bf = new BinaryFormatter();
 4 
 5 object o = bf.Deserialize(s);
 6 
 7 Person p = o as Person;
 8 if(p != null)
 9     Console.WriteLine("DeSerialized Person aged:{0} whight:{1}",p.Age,p.WeightInPounds);
10 
11 s.Close();

澳门葡京备用网址 6

 

若是必要对一部分字段体系化部分不类别化时,大家得以依照如下设置完成

澳门葡京备用网址 7

 1 [Serializable]
 2 public class Person
 3 {
 4     public Person()
 5     {
 6     }
 7 
 8     public int Age;
 9     [NonSerialized]
10     public int WeightInPounds;
11 }

澳门葡京备用网址 8

 

Serializable在C#中的功能.NET 中的对象系列化
简介
  连串化是指将对象实例的情事存款和储蓄到存款和储蓄媒体的经过。在此进度中,先将对象的公共字段和私家字段以及类的名目(包涵类所在的程序集)转换为字节流,然后再把字节流写入数据流。在跟着对指标开始展览反种类化时,将创制出与原对象完全相同的副本。
澳门葡京备用网址 9
 
 在面向对象的环境中达成类别化学工业机械制时,必须在易用性和灵活性之间开始展览局地衡量。只要你对此进程有丰裕的控制能力,就足以使该进程在非常的大程度上自行实行。
例如,不难的二进制种类化不能够满意急需,恐怕,由于特定原因须要规定类中那么些字段需求体系化。以下各部分将琢磨 .NET 框架提供的有限支撑的种类化学工业机械制,
并珍视介绍使你能够依照供给自定义系列化进度的一部分最首要效用。

愚公移山存款和储蓄
 
 我们平日供给将对象的字段值保存到磁盘中,并在以往检索此数量。就算不行使类别化也能成功那项工作,但那种艺术一般很麻烦而且便于出错,并且在要求跟踪
对象的层次结构时,会变得进一步复杂。能够设想一下编纂包涵大批量对象的重型业务应用程序的意况,程序员不得不为每二个目的编排代码,以便将字段和品质保存
至磁盘以及从磁盘还原这一个字段和总体性。种类化提供了轻松达成这一个目的的高速方法。
澳门葡京备用网址 10
 
 公共语言运营时 (CL奥迪Q7) 管理对象在内部存款和储蓄器中的分布,.NET 框架则经过接纳反射提供自动的连串化学工业机械制。对象类别化后,类的称号、程序集以及类实例
的装有数据成员均被写入存款和储蓄媒体中。对象平时用成员变量来存款和储蓄对其余实例的引用。类体系化后,连串化引擎将跟踪全数已体系化的引用对象,以保证同等对象不
被种类化数次。.NET 框架所提供的类别化体系布局得以自动正确处理对象图表和循环引用。对目的图表的唯一须求是,由正在进展系列化的靶子所引用的全数对象都必须标记为 Serializable(请参阅基本连串化)。不然,当体系化程序试图种类化未标记的靶牛时将会出现相当。
澳门葡京备用网址 11
  当反连串化已类别化的类时,将再度创立该类,并自行恢复全体数据成员的值。

按值封送
 
 对象仅在创造对象的接纳程序域中央银一蹴而就。除非对象是从 马尔斯halByRefObject 派生得到或标志为 塞里alizable,不然,任何
将对象作为参数字传送递或将其当作结果回到的品味都将战败。要是指标标记为 Serializable,则该指标将被活动连串化,并从一个使用程序域传输至另
二个应用程序域,然后进行反类别化,从而在其次个利用程序域中产生出该对象的3个纯粹副本。此进度一般号称按值封送。
澳门葡京备用网址 12
 
 借使指标是从 马尔斯halByRefObject 派生获得,则从多个施用程序域传递至另八个施用程序域的是指标引用,而不是目的自小编。也能够将
从 马尔斯halByRefObject 派生获得的对象标记为 Serializable。远程应用此指标时,负责举行系列化并已事先铺排为 SurrogateSelector 的格式化程序将控制连串化进度,并用四个代理替换全体从 马尔斯halByRefObject 派生获得的对
象。若是没有优先布署为 SurrogateSelector,连串化种类布局将遵守上边包车型大巴正统类别化规则(请参阅种类化过程的步调)。

 

大旨种类化
  要使3个类可体系化,最简易的方法是接纳 Serializable 属性对它举办标记,如下所示:

澳门葡京备用网址 13

1 [Serializable]
2 public class MyObject 
3 {
4    public int n1 = 0;
5    public int n2 = 0;
6    public String str = null;
7 }

澳门葡京备用网址 14

  以下代码片段表达了怎么将该类的三个实例系列化为2个文本:

澳门葡京备用网址 15

1 MyObject obj = new MyObject();
2 obj.n1 = 1;
3 obj.n2 = 24;
4 obj.str = "一些字符串";
5 IFormatter formatter = new BinaryFormatter();
6 Stream stream = new FileStream("MyFile.bin", FileMode.Create,
7 FileAccess.Write, FileShare.None);
8 formatter.Serialize(stream, obj);
9 stream.Close();

澳门葡京备用网址 16

  本例使用二进制格式化程序进行连串化。您只需创立三个要采纳的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要种类化的指标实例作为参数提要求此调用。类中的全部成员变量(甚至标记为 private 的变量)都将被体系化,但那一点在本例中未明朗彰显出来。在那点上,二进制系列化差别于只系列化公共字段的 XML 体系化程序。
澳门葡京备用网址 17
  将指标还原到它原先的景况也十分简单。首先,创立格式化程序和流以开始展览读取,然后让格式化程序对目的开始展览反系列化。以下代码片段表明了什么进行此操作。

澳门葡京备用网址 18

 1 IFormatter formatter = new BinaryFormatter();
 2 Stream stream = new FileStream("MyFile.bin", FileMode.Open,
 3 FileAccess.Read, FileShare.Read);
 4 MyObject obj = (MyObject) formatter.Deserialize(fromStream);
 5 stream.Close();
 6 
 7 // 下面是证明
 8 Console.WriteLine("n1: {0}", obj.n1);
 9 Console.WriteLine("n2: {0}", obj.n2);
10 Console.WriteLine("str: {0}", obj.str);

澳门葡京备用网址 19

  下面所选取的 BinaryFormatter 成效很高,能生成那一个紧凑的字节流。全体应用此格式化程序连串化的对
象也可应用它实行反类别化,对于种类化将在 .NET 平台上开始展览反系列化的对象,此格式化程序无疑是2个上佳工具。要求留意的是,对目的实行反体系化时
并不调用构造函数。对反类别化添加这项约束,是出于质量方面包车型地铁设想。然而,这违背了对象编写者日常选择的一部分运行时约定,由此,开发人士在将对象标记为可
系列化时,应确定保障考虑了这一特殊约定。
澳门葡京备用网址 20
  假如须要全部可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的格式化程序换来 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于地点运用的言传身教,该格式化程序将转变以下结果。

澳门葡京备用网址 21

<SOAP-ENV:Envelope
   xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:SOAP- ENC=http://schemas.xmlsoap.org/soap/encoding/
   xmlns:SOAP- ENV=http://schemas.xmlsoap.org/soap/envelope/
   SOAP-ENV:encodingStyle=
   "http://schemas.microsoft.com/soap/encoding/clr/1.0
  http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:a1="http://schemas.microsoft.com/clr/assem/ToFile">

   <SOAP-ENV:Body>
     <a1:MyObject id="ref-1">
       <n1>1</n1>
       <n2>24</n2>
       <str id="ref-3">一些字符串</str>
     </a1:MyObject>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

澳门葡京备用网址 22

  需求注意的是,无法持续 Serializable 属性。如若从 MyObject 派生出一个新的类,则这几个新的
类也不可能不运用该属性实行标记,否则将不可能连串化。例如,假诺打算类别化以下类实例,将会显得二个 SerializationException,说明 MyStuff 类型未标记为可连串化。

1 public class MyStuff : MyObject
2 {
3    public int n3;
4 }

  使用系列化属性分外有益,可是它存在上述的片段限制。有关什么日期标记类以开始展览种类化(因为类编写翻译后就不大概再种类化),请参见有关表明(请参阅上面包车型客车体系化规则)。

 

选拔性系列化
 
 类常常包括不应被体系化的字段。例如,假若某些类用1个分子变量来存储线程 ID。当此类被反系列化时,类别化此类时所蕴藏的 ID 对应的线程或然不
再运行,所以对这一个值进行种类化没有意义。能够透过利用 NonSerialized 属性标记成员变量来预防它们被系列化,如下所示:

澳门葡京备用网址 23

1 [Serializable]
2 public class MyObject
3 {
4     public int n1;
5     [NonSerialized] public int n2;
6     public String str;
7 }

澳门葡京备用网址 24

 

自定义连串化
 
 能够透过在对象上落到实处 ISerializable 接口来自定义连串化进度。这一功用在反体系化后成员变量的值失效时尤其有用,但是急需为变量提供值
以重建对象的完好气象。要贯彻 ISerializable,须求贯彻 GetObjectData 方法以及二个破例的构造函数,在反体系化对象时要用
到此构造函数。以下代码示例表达了哪些在前一部分中关系的 MyObject 类上达成 ISerializable。

澳门葡京备用网址 25

 1 [Serializable]
 2 public class MyObject : ISerializable
 3 {
 4     public int n1;
 5     public int n2;
 6     public String str;
 7 
 8     public MyObject()
 9     {
10     }
11 
12     protected MyObject(SerializationInfo info, StreamingContext context)
13     {
14         n1 = info.GetInt32("i");
15         n2 = info.GetInt32("j");
16         str = info.GetString("k");
17     }
18 
19     public virtual void GetObjectData(SerializationInfo info,
20                                       StreamingContext context)
21     {
22         info.AddValue("i", n1);
23         info.AddValue("j", n2);
24         info.AddValue("k", str);
25     }
26 }

澳门葡京备用网址 26

  在类别化进程中调用 GetObjectData 时,须求填写方法调用中提供的 SerializationInfo 对象。只需按名称/值
对的样式丰裕将要系列化的变量。其名称能够是其它文件。只要已体系化的数额足以在反种类化进度中回复对象,便能够自由采纳添加
至 SerializationInfo 的分子变量。若是基对象完结了 ISerializable,则派生类应调用其基对象
的 GetObjectData 方法。
澳门葡京备用网址 27
 
 要求强调的是,将 ISerializable 添加至有个别类时,供给同时实现 GetObjectData 以及特殊的构造函数。假若缺乏 GetObjectData,编写翻译器将生出警示。但是,由于非常小概强制实现构造函数,所以,缺乏构造函数时不会产生警示。假诺在没有构造函数的情景下尝
试反种类化有个别类,将会现身十分。在解除潜在安全性和版本控制难点等地点,当前统一筹划优化 SetObjectData 方法。例如,要是将 SetObjectData 方法定义为有个别接口的一片段,则此方法必须是国有措施,那使得用户只好编写代码来防备反复调
用 SetObjectData 方法。能够想象,假使某些对象正在推行有些操作,而有些恶意应用程序却调用此目标的 SetObjectData 方
法,将会滋生部分神秘的劳动。
澳门葡京备用网址 28
  在反种类化进度中,使用出于此目标而提供的构造函数将 SerializationInfo 传递给类。对象反连串化时,对构造函数的别样可知性约束都将被忽视,由此,能够将类标志为 public、protected、internal 或 private。三个不利的艺术是,在类未封装的事态下,将构造函数标记为 protect。倘诺类已打包,则应标记为 private。要上涨对象的状态,只需采纳系列化时行使的称呼,从 SerializationInfo 中搜索变量的值。借使基类实现了 ISerializable,则应调用基类的构造函数,以使基础对象能够还原其变量。
澳门葡京备用网址 29
  假设从贯彻了 ISerializable 的类派生出贰个新的类,则只要新的类中蕴藏其余索要连串化的变量,就必须同时完毕构造函数以及 GetObjectData 方法。以下代码片段展现了怎么样运用上文所示的 MyObject 类来完结此操作。

澳门葡京备用网址 30

 1 [Serializable]
 2 public class ObjectTwo : MyObject
 3 {
 4     public int num;
 5 
 6     public ObjectTwo() : base()
 7     {
 8     }
 9 
10     protected ObjectTwo(SerializationInfo si, StreamingContext context) :
11         base(si,context)
12     {
13         num = si.GetInt32("num");
14     }
15 
16     public override void GetObjectData(SerializationInfo si,
17                                        StreamingContext context)
18     {
19         base.GetObjectData(si,context);
20         si.AddValue("num", num);
21     }
22 }

澳门葡京备用网址 31

  切记要在反连串化构造函数中调用基类,不然,将永生永世不会调用基类上的构造函数,并且在反类别化后也无力回天创设完全的目的。
澳门葡京备用网址 32
 
 对象被彻底重新营造,可是在反类别化进度中调用方法恐怕会带来不良的副效用,因为被调用的法子或者引用了在调用时没有反类别化的目的引用。要是正在展开
反体系化的类完毕了 IDeserializationCallback,则反连串化整个对象图表后,将自行调用 OnSerialization 方
法。此时,引用的全数子对象均已全然恢复生机。有个别类不选取上述事件侦听器,很难对它们进行反类别化,散列表就是多少个超人的例子。在反体系化进度中摸索关键字/值对格外不难,不过,由于一点都不大概担保从散列表派生出的类已反种类化,所以把那么些指标添加回散列表时会现出局地难题。由此,提议近期毫不在散列表上调用方法。
澳门葡京备用网址 33
类别化进度的步子
  在格式化程序上调用 Serialize 方法时,对象系列化根据以下规则进行:
澳门葡京备用网址 34
  检查格式化程序是还是不是有代理选用器。假如有,检查代理选用器是还是不是处理钦命项指标对象。假设选拔器处理此指标类型,将在代理采纳器上调用 ISerializable.GetObjectData。
  若是没有代理选拔器或有却不处理此类型,将检查是还是不是选择 Serializable 属性对指标开始展览标记。尽管未标记,将会引发 SerializationException。
  若是目的已被正确标记,将检核对象是或不是落到实处了 ISerializable。若是已落到实处,将在对象上调用 GetObjectData。
  假若目的未兑现 Serializable,将利用默许的连串化策略,对富有未标记为 NonSerialized 的字段都进行体系化。
  版本控制
 
 .NET 框架扶助版本控制和并排执行,并且,假诺类的接口保持一致,全数类均可跨版本工作。由于类别化涉及的是成员变量而非接口,所以,在向要跨版本
类别化的类中添加成员变量,或从中删除变量时,应严俊行事。特别是对于未落实 I塞里alizable 的类更应如此。若当前版本的情状发生了别样变
化(例如添加成员变量、更改变量类型或改变变量名称),都表示一旦一致类型的依存对象是应用最初版本举行种类化的,则无从得逞对它们举办反系列化。
澳门葡京备用网址 35
  假诺目的的意况必要在差别版本间发生变动,类的小编能够有三种选拔:
澳门葡京备用网址 36
  达成 ISerializable。那使你能够规范地控制连串化和反系列化进度,在反系列化进程中正确地拉长和解说以后意况。
  使用 NonSerialized 属性标记不重庆大学的积极分子变量。仅当预测类在分裂版本间的变通较小时,才可采用这一个选项。例如,把二个新变量添加至类的较高版本后,能够将该变量标记为 NonSerialized,以保证该类与早期版本保持包容。

种类化规则
 
 由于类编写翻译后便无计可施连串化,所以在筹划新类时应考虑连串化。必要考虑的难点有:是或不是必须跨应用程序域来发送此类?是还是不是要远程应用此类?用户将何以采纳此
类?恐怕他们会从自个儿的类中派生出三个急需种类化的新类。只要有那种大概,就应将类标志为可种类化。除下列情状以外,最好将全部类都标志为可连串化:
澳门葡京备用网址 37
  全体的类都永远也不会抢先应用程序域。如若有个别类不必要种类化但需求跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
  类存款和储蓄仅适用于其眼下实例的特种指针。例如,即使有些类富含非受控的内部存储器或文件句柄,请保管将那么些字段标记为 NonSerialized 或根本不种类化此类。
  有些数据成员包蕴敏感消息。在那种情状下,提议落实 ISerializable 并仅体系化所必要的字段。 

转自:

1.AdminUserInfo.cs

值类型直接存款和储蓄对象,而引用类型存款和储蓄对象的地点,在对引用类型实行理并答复制的时候,也只是复制对象的地点。

缘何要使用连串化?

[Serializable]队列化类——System.塞里alizableAttribute

一齐复制一个引用类型对象主要有三种情势:

1.额外添加贰个构造函数,入参为待复制对象(即使字段为引用类型,需求继续添加构造函数,这样景况会变的十二分复杂。)

    public class Test1
    {
        private int field1;
        private int field2;
        private int field3;
        public Test1()
        { 

        }

        public Test1(Test1 test1)
        {
            this.field1 = test1.field1;
            this.field2 = test1.field2;
            this.field3 = test1.field3;
        }
    }

2.选用系列化反种类化(对品质会有杀伤)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Test t1 = new Test();
            Console.WriteLine(t1.list.Count);
            Test t2 = (Test)Clone(t1);
            t2.list.Add("");
            Console.WriteLine(t2.list.Count);
            Console.WriteLine(t1.list.Count);
            Console.ReadLine();
        }

        public static object Clone(object obj)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            ms.Position = 0;
            return (bf.Deserialize(ms)); ;
        }
    }

    [Serializable]
    public class Test
    {
        public List<string> list = new List<string>();
    }
}

3.利用反射(测试了一个网上的接口可用,可是对质量杀伤和类别化反类别化分外,而且对代码混淆有自然影响。 
 

最要紧的八个原因是:

串行化是指储存和获取磁盘文件、内部存款和储蓄器或其余地点中的对象。在串行化时,全数的实例数据都保留到存款和储蓄介质上,在废除串行化时,对象会被复苏,且不可能与其原实例差异开来。

1.     
将对象的景观保存在存款和储蓄媒体中以便能够在随后重新成立出完全相同的副本;

只需给类添加Serializable属性,就足以兑现串行化实例的积极分子。

2.     
按值将对象从2个利用程序域发送至另1个选拔程序域。

并行化是串行化的逆进度,数据从存款和储蓄介质中读取出来,并赋给类的实例变量。

诸如,类别化可用来在 ASP.NET
中保存会话状态,以及将目的复制到 Windows
窗体的剪贴板中。

例:

它还可用以按值将指标从一个行使程序域远程传递至另二个选择程序域。

 

本文简要介绍了 Microsoft .NET
中选取的连串化。

1 [Serializable]
2 public class Person
3 {
4 public Person()
5 {
6 }
7
8 public int Age;
9 public int WeightInPounds;
10 }

 

一、        简介

using System.Runtime.Serialization.Formatters.Binary;

 

下边的代码将目的Person举办种类化并储存到2个文书中

类别化是指将指标实例的景况存款和储蓄到存款和储蓄媒体的长河。

 

在此进程中,

1 Person me = new Person();
2
3 me.Age = 34;
4 me.WeightInPounds = 200;
5
6 Stream s = File.Open("Me.dat",FileMode.Create);
7
8 BinaryFormatter bf = new BinaryFormatter();
9
10 bf.Serialize(s,me);
11
12 s.Close();

1.     
先将目的的集体字段和私家字段以及类的名目(包罗类所在的程序集)转换为字节流,

NET中的对象连串化,引用类型对象的深拷贝。 

2.      然后再把字节流写入数据流。

接下来再举2个并行化的例证

3.     
在随着对目的开始展览反类别化时,将创造出与原对象完全相同的副本。

Stream s = File.Open("Me.dat",FileMode.Open);

BinaryFormatter bf = new BinaryFormatter();

object o = bf.Deserialize(s);

Person p = o as Person;
if(p != null)
Console.WriteLine("DeSerialized Person aged:{0} whight:{1}",p.Age,p.WeightInPounds);

s.Close();

在面向对象的条件中达成系列化学工业机械制时,必须在易用性和灵活性之间开始展览局地权衡。

 

借使你对此进程有丰盛的控制能力,就足以使该进程在很大程度上电动举行。例如,简单的二进制体系化不可能满足急需,或许,由于特定原因供给规定类中那么些字段供给类别化。

只要急需对有的字段体系化部分不连串化时,大家能够依据如下设置完毕

以下各部分将探讨 .NET
框架提供的保障的连串化机制,并珍视介绍使您能够遵照要求自定义连串化进程的一些主要成效。

[Serializable]
public class Person
{
public Person()
{
}

public int Age;
[NonSerialized]
public int WeightInPounds;
}

② 、         持久存款和储蓄

我们通常需求将对象的字段值保存到磁盘中,并在此后检索此数额。

就算不应用体系化也能不负众望这项工作,但那种艺术一般很麻烦而且便于出错,并且在要求跟踪对象的层次结构时,会变得更为复杂。

能够想象一下编辑包括多量对象的大型业务应用程序的情景,程序员不得不为每多个指标编排代码,以便将字段和品质保存至磁盘以及从磁盘还原那一个字段和总体性。

体系化提供了轻松达成这么些目的的连忙方法。

集身体语言言运维时 (CLENCORE)
管理对象在内部存款和储蓄器中的分布,.NET
框架则经过使用反射提供自动的类别化学工业机械制。

指标连串化后,类的称呼、程序集以及类实例的兼具数据成员均被写入积存媒体[本文中的存款和储蓄媒体是何等?xml?]中。

对象一般用成员变量来囤积对其它实例的引用。类类别化后,种类化引擎将跟踪全数已系列化的引用对象,以管教同等对象不被系列化多次[类别化是针对性对象的?那岂不是贰个顺序会须要过多的连串化?]。

.NET
框架所提供的类别化种类布局得以自行正确处理对象图表和巡回引用。

对目的图表[哪些是目的图表?]的绝无仅有供给是,由正在开始展览连串化的靶子所引述的具有目的都无法不标记为
Serializable(请参阅主导体系化澳门葡京备用网址,)。不然,当种类化程序试图系列化未标记的对象时将会出现极度。

当反种类化已系列化的类时,将再也成立该类,并活动回复全体数据成员的值。

 Serializable在C#中的功用.NET 中的对象系列化
澳门葡京备用网址 38
澳门葡京备用网址 39简介
澳门葡京备用网址 40种类化是指将对象实例的情况存储到存款和储蓄媒体的长河。在此进程中,先将对象的集体字段和个人字段以及类的名目(包涵类所在的程序集)转换为字节流,然后再把字节流写入数据流。在紧接着对目的举行反体系化时,将创立出与原对象完全相同的副本。
澳门葡京备用网址 41
澳门葡京备用网址 42在面向对象的条件中贯彻种类化机制时,必须在易用性和灵活性之间展开一些衡量。只要您对此进程有丰富的控制能力,就能够使该进程在非常大程度上机关进行。例如,简单的二进制连串化不能够满意急需,或许,由于特定原因须要明显类中那个字段供给类别化。以下各部分将探索 .NET 框架提供的可相信的类别化学工业机械制,一视同仁点介绍使你能够依据须要自定义连串化进度的局地最重要效率。
澳门葡京备用网址 43
澳门葡京备用网址 44慎始而敬终存款和储蓄
澳门葡京备用网址 45小编们常常要求将对象的字段值保存到磁盘中,并在其后检索此数量。就算不使用体系化也能实现那项工作,但那种办法一般很麻烦而且简单失误,并且在须求跟踪对象的层次结构时,会变得愈加复杂。能够设想一下编写制定包罗大量目的的重型业务应用程序的意况,程序员不得不为每二个指标编排代码,以便将字段和属性保存至磁盘以及从磁盘还原这个字段和质量。体系化提供了轻松完毕这些指标的飞快方法。
澳门葡京备用网址 46
澳门葡京备用网址 47公共语言运营时 (CL奥迪Q5) 管理对象在内存中的分布,.NET 框架则经过动用反射提供自动的类别化学工业机械制。对象类别化后,类的称谓、程序集以及类实例的拥有数据成员均被写入存款和储蓄媒体中。对象平时用成员变量来囤积对别的实例的引用。类连串化后,种类化引擎将跟踪全数已系列化的引用对象,以有限支撑同等对象不被种类化数十次。.NET 框架所提供的连串化类别布局得以自行正确处理对象图表和巡回引用。对指标图表的唯一须求是,由正在进展种类化的指标所引述的有所目标都必须标记为 Serializable(请参阅基本连串化)。否则,当连串化程序试图类别化未标记的指标时将会出现非常。
澳门葡京备用网址 48
澳门葡京备用网址 49当反体系化已体系化的类时,将再次创建该类,并机关回复全体数据成员的值。
澳门葡京备用网址 50
澳门葡京备用网址 51按值封送
澳门葡京备用网址 52指标仅在创立对象的采纳程序域中卓有成效。除非对象是从 MarshalByRefObject 派生获得或标志为 Serializable,不然,任何将目的作为参数传递或将其看做结果重临的尝试都将退步。假诺目的标记为 Serializable,则该指标将被活动连串化,并从3个利用程序域传输至另2个利用程序域,然后开始展览反系列化,从而在其次个使用程序域中发出出该对象的七个准确无误副本。此进程一般号称按值封送。
澳门葡京备用网址 53
澳门葡京备用网址 54比方目的是从 马尔斯halByRefObject 派生获得,则从二个运用程序域传递至另一个运用程序域的是目的引用,而不是目的自笔者。也得以将从 MarshalByRefObject 派生得到的指标标记为 塞里alizable。远程应用此目的时,负责实行连串化并已先期布置为 SurrogateSelector 的格式化程序将控制类别化进程,并用二个代理替换全体从 马尔斯halByRefObject 派生得到的靶子。就算没有先行安顿为 SurrogateSelector,体系化连串布局将遵循上边包车型大巴正儿八经连串化规则(请参阅种类化进度的步调)。
澳门葡京备用网址 55
澳门葡京备用网址 56主导连串化
澳门葡京备用网址 57要使1个类可体系化,最简易的章程是运用 Serializable 属性对它举办标记,如下所示:
澳门葡京备用网址 58

叁 、        按值封送

对象仅在创制对象的选用程序域中央银立竿见影。除非对象是从 MarshalByRefObject
派生得到或标志为 Serializable,不然,任何将对象作为参数字传送递或将其当作结果回到的品味都将破产。

倘若目的标记为 Serializable[何以标记为Serializable],则该对象将被电动连串化,并从三个行使程序域传输至另3个接纳程序域,然后举行反体系化,从而在其次个利用程序域中生出出该指标的二个准确无误副本。此进度一般号称按值封送

要是指标是从 MarshalByRefObject
派生得到,则从三个选拔程序域传递至另1个用到程序域的是目的引用,而不是指标自小编。

也足以将从 MarshalByRefObject 派生得到的指标标记为 Serializable

远程应用此指标时,负责进行体系化并已先行布署为 SurrogateSelector
的格式化程序将决定系列化进程,并用二个代理替换全体从 MarshalByRefObject
派生得到的对象。假诺没有事先安顿为 SurrogateSelector,连串化种类布局将信守下面包车型客车行业内部类别化规则(请参阅连串化进度的手续)。

[Serializable]
public class MyObject {
   public int n1 = 0;
   public int n2 = 0;
   public String str = null;
}

④ 、        基本连串化

要使3个类可种类化,最简单易行的法门是利用 Serializable 属性[何以webservice中平昔不标记Serializable?]

对它举办标记,如下所示:

[Serializable]

 public class MyObject {

  public int n1 = 0;

  public int n2 = 0;

  public String str = null;

}

以下代码片段表达了什么将此类的1个实例连串化为二个文本[咱俩不须要用手写这个代码吧?]:

MyObject obj = new MyObject();

obj.n1 = 1;

obj.n2 = 24;

obj.str = “一些字符串”;

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream(“MyFile.bin”,
FileMode.Create,

FileAccess.Write, FileShare.None);

formatter.Serialize(stream, obj);

stream.Close();

本例使用二进制格式化程序开始展览体系化。

您只需成立多少个要动用的流和格式化程序的实例,然后调用格式化程序的 Serialize
方法。流和要类别化的目的实例作为参数提需要此调用。

类中的全体成员变量(甚至标记为 private
的变量)都将被连串化,但那一点在本例中未明朗浮现出来。

在那点上,二进制体系化区别于只体系化公共字段的 XML
体系化程序[共有多少种系列化?二进制连串化和xml种类化分别用在哪些地方?二进制/XML是或不是正是本文所说的蕴藏媒体?]。

将目的还原到它原先的动静也相当简单。

首先,制造格式化程序和流以拓展读取,

下一场让格式化程序对目的开始展览反系列化。

以下代码片段表明了怎样进展此操作。

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream(“MyFile.bin”,
FileMode.Open,

FileAccess.Read, FileShare.Read);

MyObject obj = (MyObject)
formatter.Deserialize(fromStream);

stream.Close();

 

// 上边是印证

Console.WriteLine(“n1: {0}”, obj.n1);

Console.WriteLine(“n2: {0}”, obj.n2);

Console.WriteLine(“str: {0}”, obj.str);

地点所运用的 BinaryFormatter 作用很高,能生成尤其严密的字节流。

具备应用此格式化程序连串化的指标也可使用它实行反种类化,对于系列化将在 .NET
平台上进展反种类化的对象,此格式化程序无疑是二个完好无损工具。

须要留意的是,对指标实行反系列化时并不调用构造函数[不调用构造函数,会不会为编制程序带来影响,例如不能在构造函数中添加逻辑?还是,不供给关切构造函数,因为对象的变量足以注明对象的景观?]。对反种类化添加那项约束,是出于品质方面包车型地铁考虑[不调用构造函数?者对品质会有多大影响,这么说调用构造函数并不是截然没有需求?]。不过,那违背了对象编写者平日选用的局地周转时约定,由此,开发职员在将对象标记为可种类化时,应保险考虑了这一至极约定。

假如供给具有可移植性,请使用 SoapFormatter。所要做的更动只是将上述代码中的格式化程序换到
SoapFormatter,而 SerializeDeserialize 调用不变。

对此地点运用的演示,该格式化程序将转变以下结果。

<SOAP-ENV:Envelope

 
xmlns:xsi=

  xmlns:xsd=””

  xmlns:SOAP-
ENC=

  xmlns:SOAP-
ENV=

  SOAP-ENV:encodingStyle=

 

  “

 
xmlns:a1=”;

 

  <SOAP-ENV:Body>

    <a1:MyObject id=”ref-1″>

      <n1>1</n1>

      <n2>24</n2>

      <str id=”ref-3″>一些字符串</str>

    </a1:MyObject>

  </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

须求留意的是,不也许继承 Serializable 属性。如果从 MyObject
派生出贰个新的类,则那些新的类也亟须接纳该属性举行标记,不然将无法类别化。[如果Serializable
属性无法三番五次,为何webservice类中尚无设置Serializable 属性?]

诸如,要是准备体系化以下类实例,将会彰显贰个 SerializationException,说明 MyStuff
类型未标记为可种类化。

public class MyStuff : MyObject

{

  public int n3;

}

运用种类化属性非凡便宜,然则它存在上述的一部分限制。

关于曾几何时标记类以举办系列化(因为类编写翻译后就不恐怕再体系化),请参考有关表达(请参阅上面包车型客车类别化规则)。

澳门葡京备用网址 59以下代码片段表达了怎样将此类的贰个实例系列化为1个文书:
澳门葡京备用网址 60

伍 、        选用性类别化

类一般包罗不应被系列化的字段。例如,借使某些类用三个分子变量来存款和储蓄线程 ID。当此类被反类别化时,类别化此类时所蕴藏的 ID
对应的线程或然不再运行,所以对那些值实行连串化没有意义。

能够由此选拔 NonSerialized 属性标记成员变量来幸免它们被种类化,如下所示:

[Serializable]

public class MyObject

{

  public int n1;

  [NonSerialized] public int n2;

  public String str;

}

MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "一些字符串";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();

⑥ 、        自定义系列化

能够透过在对象上落到实处 ISerializable 接口来自定义体系化进度[自定义体系化进程是怎样,本身写代码体系化,反类别化对象?]。

这一意义在反连串化后成员变量的值失效时特别有用,不过急需为变量提供值以重建对象的完好气象。

要实现 ISerializable,须求落成 GetObjectData
方法以及三个分外的构造函数[不是反种类化的时候,不调用构造函数吗?],在反体系化对象时要用到此构造函数。

以下代码示例表达了什么样在前一部分中涉及的 MyObject 类上贯彻
ISerializable

[Serializable]

public class MyObject : ISerializable

{

  public int n1;

  public int n2;

  public String str;

 

  public MyObject()

  {

  }

 

  protected MyObject(SerializationInfo info,
StreamingContext context)

  {

    n1 = info.GetInt32(“i”);

    n2 = info.GetInt32(“j”);

    str = info.GetString(“k”);

  }

 

  public virtual void GetObjectData(SerializationInfo
info,

StreamingContext context)

  {

    info.AddValue(“i”, n1);

    info.AddValue(“j”, n2);

    info.AddValue(“k”, str);

  }

}

在类别化进程中调用 GetObjectData 时,要求填写方法调用中提供的 SerializationInfo
对象。只需按名称/值对的花样丰硕将要类别化的变量。其名称能够是其余公文。只要已系列化的数额足以在反类别化进度中恢复生机对象,便能够自由采纳添加至
SerializationInfo
的积极分子变量。要是基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData 方法。

内需强调的是,将 ISerializable 添加至某些类时,须求同时达成 GetObjectData
以及特种的构造函数。假使缺少 GetObjectData,编写翻译器将生出警示。可是,由于不只怕强制完结构造函数,所以,紧缺构造函数时不会发生警示。如果在未曾构造函数的意况下品尝反种类化某些类,将会出现很是。

在拔除潜在安全性和版本控制问题等方面,当前规划优于 SetObjectData
方法。例如,如果将 SetObjectData
方法定义为有个别接口的一部分,则此办法必须是共用艺术,那使得用户只好编写代码来预防反复调用
SetObjectData
方法。能够想像,倘使某些对象正在实践某个操作,而有些恶意应用程序却调用此目的的
SetObjectData
方法,将会唤起局部诡秘的劳顿。

在反种类化进程中,使用出于此指标而提供的构造函数将 SerializationInfo
传递给类。对象反类别化时,对构造函数的别的可知性约束都将被忽视,由此,能够将类标志为 public、protected、internal 或 private。

三个正确的法子是,在类未封装的意况下,将构造函数标记为 protect。假若类已打包,则应标记为
private。要东山再起对象的事态,只需采取连串化时利用的称谓,从 SerializationInfo
中检索变量的值。如若基类落成了 ISerializable,则应调用基类的构造函数,以使基础对象足以还原其变量。

假使从贯彻了 ISerializable
的类派生出多少个新的类,则只要新的类中富含别的索要体系化的变量,就非得同时达成构造函数以及
GetObjectData
方法。

以下代码片段展现了哪些运用上文所示的 MyObject
类来形成此操作。

[Serializable]

public class ObjectTwo : MyObject

{

  public int num;

 

  public ObjectTwo() : base()

  {

  }

 

  protected ObjectTwo(SerializationInfo si,
StreamingContext context) :

base(si,context)

  {

    num = si.GetInt32(“num”);

  }

 

  public override void
GetObjectData(SerializationInfo si,

StreamingContext context)

  {

    base.GetObjectData(si,context);

    si.AddValue(“num”, num);

  }

}

牢记要在反连串化构造函数中调用基类,否则,将永远不会调用基类上的构造函数,并且在反系列化后也手足无措营造一体化的对象。

对象被彻底重新营造,但是在反连串化进程中调用方法只怕会推动不良的副成效,因为被调用的法子或者引用了在调用风尚未反类别化的对象引用[不明白怎么样看头?是眼下指标,照旧别的对象?]。

设若正在拓展反体系化的类达成了 DeserializationCallback,则反体系化整个对象图表后,将活动调用
OnSerialization
方法。此时,引用的全部子对象均已全然复苏。

稍许类不选拔上述事件侦听器,很难对它们进行反类别化,散列表[何以是散列表?]就是二个名列前茅的事例。

在反种类化进度中检索关键字/值对10分简单,然则,由于不可能担保从散列表派生出的类已反体系化,所以把那几个目的添加回散列表时会油然则生一些难题。因而,提出最近无须在散列表上调用方法。

澳门葡京备用网址 61本例使用二进制格式化程序实行系列化。您只需成立两个要运用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要种类化的靶子实例作为参数提需求此调用。类中的全体成员变量(甚至标记为 private 的变量)都将被系列化,但那一点在本例中未分明体现出来。在那或多或少上,二进制体系化分化于只连串化公共字段的 XML 连串化程序。
澳门葡京备用网址 62
澳门葡京备用网址 63将对象还原到它原先的情事也至极简单。首先,创立格式化程序和流以进行读取,然后让格式化程序对指标开始展览反系列化。以下代码片段说明了什么样开始展览此操作。
澳门葡京备用网址 64

七 、        系列化进程的步子

在格式化程序上调用 Serialize 方法时,对象系列化遵照以下规则进行:

  • 反省格式化程序是还是不是有代理选择器[是否连串化的靶子中所引用的对象都必须是可连串化的对象,不然不能够反种类化。那么,是或不是webservice无法引用未系列化的靶子?]。假使有,检查代理接纳器是还是不是处理钦赐项目标目的。即使选择器处理此指标类型,将在代理选择器上调用
    ISerializable.GetObjectData
  • 一旦没有代理选择器或有却不处理此类型,将检查是还是不是采用 Serializable
    属性对目的开始展览标记。假若未标记,将会掀起 SerializationException

  • 设若指标已被科学标记,将检核查象是否落到实处了 ISerializable。假诺已实现,将在指标上调用
    GetObjectData

  • 万一指标未完结 Serializable,将采取暗中同意的体系化策略,对负有未标记为
    NonSerialized
    的字段都进行体系化。

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(fromStream);
stream.Close();

// 下面是证明
Console.WriteLine("n1: {0}", obj.n1);
Console.WriteLine("n2: {0}", obj.n2);
Console.WriteLine("str: {0}", obj.str);

⑧ 、        版本控制

.NET
框架支持版本控制和并排执行,并且,尽管类的接口保持一致,全数类均可跨版本工作。

出于体系化涉及的是成员变量而非接口,所以,在向要跨版本类别化的类中添加成员变量,或从中删除变量时,应审慎行事。越发是对此未兑现
ISerializable
的类更应如此。

若当前版本的地方发生了别样变动(例如添加成员变量、更改变量类型或变更变量名称),都代表假若相同品种的幸存对象是采纳最初版本举办系列化的,则不能得逞对它们进行反类别化。

如若指标的状态须求在分裂版本间产生转移,类的作者能够有二种选取:

  • 实现 ISerializable。那使你可以精确地决定种类化和反类别化进程,在反种类化进程中正确地加上和表明未来景观。
  • 使用 NonSerialized
    属性标记不首要的积极分子变量。仅当预测类在区别版本间的生成较小时,才可应用那些选项。例如,把2个新变量添加至类的较高版本后,能够将该变量标记为
    NonSerialized,以保险该类与早期版本保持相当[连串化对象中包蕴NonSerialized标记,是或不是有隐患?]。

澳门葡京备用网址 65下边所选用的 BinaryFormatter 效能很高,能生成那些紧凑的字节流。全部应用此格式化程序种类化的对象也可应用它实行反连串化,对于连串化将在 .NET 平台上展开反种类化的靶子,此格式化程序无疑是一个杰出工具。必要专注的是,对目的进行反连串化时并不调用构造函数。对反连串化添加这项约束,是由于质量方面包车型地铁考虑。可是,那违反了对象编写者平时使用的片段运营时约定,由此,开发人士在将对象标记为可系列化时,应确定保障考虑了这一新鲜约定。
澳门葡京备用网址 66
澳门葡京备用网址 67尽管供给全体可移植性,请使用 SoapFormatter。所要做的改变只是将上述代码中的格式化程序换来 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于地点运用的示范,该格式化程序将转移以下结果。
澳门葡京备用网址 68

九 、        系列化规则

出于类编写翻译后便无计可施系列化[类别化的机会是什么样时候,由哪个人(CLLAND照旧其他)来贯彻类别化?凡连串化的空子是怎么时候,由哪个人来完结?那么,webservice是怎样时候连串化,什么日期反连串化?][类编写翻译后便不可能再种类化?是还是不是类和对象都得以种类化?][类别化是还是不是和原数据表单联系相当的细致?],所以在安插新类时应考虑系列化。

急需考虑的标题有:

1.      是还是不是必须跨应用程序域来发送此类?

2.      是或不是要远程应用此类?

3.      用户将怎么样利用此类?

大概他们会从自家的类中派生出1个索要系列化的新类。只要有那种恐怕性,就应将类标志为可连串化。除下列景况以外,最好将全体类都标志为可系列化:

  • 抱有的类都永远也不会超过应用程序域。借使有个别类不要求种类化但供给跨越应用程序域,请从
    MarshalByRefObject
    派生此类。
  • 类存款和储蓄仅适用于其近期实例的13分指针。例如,假若有些类富含非受控的内部存款和储蓄器或文件句柄,请确定保证将这几个字段标记为
    NonSerialized
    或根本不系列化此类。
  • 一点数据成员包涵敏感音信。在那种情景下,提出落到实处 ISerializable
    并仅系列化所供给的字段。

自笔者的题目:

1:本文中的存款和储蓄媒体是哪些?xml?

2:种类化是对准对象的?那岂不是七个顺序会必要广大的类别化?

3:什么是目的图表?

4:怎么样标记为Serializable?在类中,标记Serializable天性?

5:为啥webservice类中并未标记Serializable?

6:一般景色下,大家不要求用手写那几个类别化,反体系化代码吧?

7:共有多少种类别化?二进制体系化和xml种类化分别用在什么样地方?二进制/XML是还是不是就是本文所说的储存媒体?

8:不调用构造函数,会不会为编制程序带来影响,例如不能够在构造函数中添加逻辑?依然,不必要关爱构造函数,因为对象的变量足以注明对象的情景?

9:反类别化不调用构造函数?者对质量会有多大影响,这么说调用构造函数并不是截然没有要求?

10:如果Serializable
属性不可能三番五次,为啥webservice类中尚无安装Serializable 属性?

11:自定义类别化进程是如何,自个儿写代码系列化,反体系化对象?

12:反体系化的时候,不可能调用构造函数吗?

13:对象被彻底重新创设,然则在反连串化进度中调用方法大概会带来不良的副成效,因为被调用的章程恐怕引用了在调用时未尝反种类化的靶子引用[不理解怎么样意思?是日前指标,依然其余对象?]。

14:什么是散列表?

15:是或不是类别化的对象中所引用的指标都无法不是可连串化的指标,不然十分的小概反系列化。那么,是否webservice无法引用未系列化的对象?

16:序列化对象中隐含NonSerialized标记,是还是不是有隐患?

17:体系化的火候是怎么样时候,由何人(CL路虎极光依旧其余)来落成连串化?凡类别化的机会是如何时候,由哪个人来完结?那么,webservice是何等时候体系化,曾几何时反系列化?

18:类编写翻译后便无能为力再种类化?是否类和目的都可以体系化?

19:类别化是否和原数据表单联系非常的细心?

<SOAP-ENV:Envelope
   xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:SOAP- ENC=http://schemas.xmlsoap.org/soap/encoding/
   xmlns:SOAP- ENV=http://schemas.xmlsoap.org/soap/envelope/
   SOAP-ENV:encodingStyle=
   "http://schemas.microsoft.com/soap/encoding/clr/1.0
  http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:a1="http://schemas.microsoft.com/clr/assem/ToFile">

   <SOAP-ENV:Body>
     <a1:MyObject id="ref-1">
       <n1>1</n1>
       <n2>24</n2>
       <str id="ref-3">一些字符串</str>
     </a1:MyObject>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

 

澳门葡京备用网址 69亟需专注的是,不能持续 Serializable 属性。假设从 MyObject 派生出一个新的类,则这一个新的类也无法不运用该属性举办标记,不然将无法种类化。例如,假设准备系列化以下类实例,将会呈现二个 SerializationException,表达 MyStuff 类型未标记为可类别化。
澳门葡京备用网址 70

public class MyStuff : MyObject
{
   public int n3;
}

澳门葡京备用网址 71动用种类化属性卓殊有益,然而它存在上述的部分限制。有关曾几何时标记类以开始展览种类化(因为类编写翻译后就无法再系列化),请参见有关注明(请参阅下边包车型客车种类化规则)。
澳门葡京备用网址 72
澳门葡京备用网址 73选取性系列化
澳门葡京备用网址 74类经常包涵不应被连串化的字段。例如,要是某些类用3个成员变量来存款和储蓄线程 ID。当此类被反种类化时,种类化此类时所蕴藏的 ID 对应的线程恐怕不再运维,所以对那几个值实行体系化没有意义。可以通过使用 NonSerialized 属性标记成员变量来防护它们被系列化,如下所示:
澳门葡京备用网址 75

[Serializable]
public class MyObject
{
   public int n1;
   [NonSerialized] public int n2;
   public String str;
}

澳门葡京备用网址 76自定义种类化
澳门葡京备用网址 77能够经过在指标上完结 ISerializable 接口来自定义种类化进程。这一效率在反体系化后成员变量的值失效时特别有用,但是急需为变量提供值以重建对象的全体气象。要实现 ISerializable,须要贯彻 GetObjectData 方法以及四个特有的构造函数,在反种类化对象时要用到此构造函数。以下代码示例表明了如何在前一部分中涉及的 MyObject 类上落到实处 ISerializable。
澳门葡京备用网址 78

[Serializable]
public class MyObject : ISerializable
{
   public int n1;
   public int n2;
   public String str;

   public MyObject()
   {
   }

   protected MyObject(SerializationInfo info, StreamingContext context)
   {
     n1 = info.GetInt32("i");
     n2 = info.GetInt32("j");
     str = info.GetString("k");
   }

   public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
   {
     info.AddValue("i", n1);
     info.AddValue("j", n2);
     info.AddValue("k", str);
   }
}

澳门葡京备用网址 79在种类化进度中调用 GetObjectData 时,供给填写方法调用中提供的 SerializationInfo 对象。只需按名称/值对的样式丰裕将要种类化的变量。其名称可以是别的文件。只要已系列化的数据足以在反系列化进程中回复对象,便能够自由选用添加至 SerializationInfo 的分子变量。假设基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData 方法。
澳门葡京备用网址 80
澳门葡京备用网址 81亟需强调的是,将 ISerializable 添加至有些类时,供给同时落到实处 GetObjectData 以及特种的构造函数。假设缺失 GetObjectData,编写翻译器将产生警告。然而,由于无法强制达成构造函数,所以,贫乏构造函数时不会生出警告。即使在一直不构造函数的情形下品尝反体系化某些类,将会现身非常。在排除潜在安全性和版本控制难题等地点,当前统一筹划优化 SetObjectData 方法。例如,尽管将 SetObjectData 方法定义为有些接口的一片段,则此方法必须是公私艺术,那使得用户只好编写代码来防备反复调用 SetObjectData 方法。可以想象,假设有些对象正在推行有些操作,而有些恶意应用程序却调用此目的的 SetObjectData 方法,将会唤起部分秘密的劳顿。
澳门葡京备用网址 82
澳门葡京备用网址 83在反体系化进度中,使用出于此指标而提供的构造函数将 SerializationInfo 传递给类。对象反体系化时,对构造函数的此外可知性约束都将被忽略,因而,能够将类标志为 public、protected、internal 或 private。三个正确的不二法门是,在类未封装的情景下,将构造函数标记为 protect。要是类已打包,则应标记为 private。要苏醒对象的动静,只需选取类别化时利用的称谓,从 SerializationInfo 中寻觅变量的值。假使基类完结了 ISerializable,则应调用基类的构造函数,以使基础对象能够还原其变量。
澳门葡京备用网址 84
澳门葡京备用网址 85只要从落实了 ISerializable 的类派生出二个新的类,则只要新的类中富含别的索要体系化的变量,就无法区别时落到实处构造函数以及 GetObjectData 方法。以下代码片段展现了怎么样使用上文所示的 MyObject 类来形成此操作。
澳门葡京备用网址 86

[Serializable]
public class ObjectTwo : MyObject
{
   public int num;

   public ObjectTwo() : base()
   {
   }

   protected ObjectTwo(SerializationInfo si, StreamingContext context) :
base(si,context)
   {
     num = si.GetInt32("num");
   }

   public override void GetObjectData(SerializationInfo si,
StreamingContext context)
   {
     base.GetObjectData(si,context);
     si.AddValue("num", num);
   }
}

澳门葡京备用网址 87切记要在反类别化构造函数中调用基类,不然,将永生永世不会调用基类上的构造函数,并且在反体系化后也无从营造完全的指标。
澳门葡京备用网址 88
澳门葡京备用网址 89对象被彻底重新营造,可是在反连串化进度中调用方法恐怕会推动不良的副功用,因为被调用的主意大概引用了在调用时并未反连串化的靶子引用。假诺正在展开反种类化的类完毕了 IDeserializationCallback,则反系列化整个对象图表后,将自行调用 OnSerialization 方法。此时,引用的全数子对象均已完全苏醒。有个别类不选取上述事件侦听器,很难对它们进行反种类化,散列表就是3个超人的事例。在反类别化进程中搜索关键字/值对极度简单,然则,由于无法担保从散列表派生出的类已反系列化,所以把这个目的添加回散列表时会现出局地标题。由此,提议最近毫不在散列表上调用方法。
澳门葡京备用网址 90
澳门葡京备用网址 91系列化进程的步调
澳门葡京备用网址 92在格式化程序上调用 Serialize 方法时,对象体系化根据以下规则举行:
澳门葡京备用网址 93
澳门葡京备用网址 94检查格式化程序是不是有代理采用器。若是有,检查代理选取器是不是处理内定项指标靶子。假使选用器处理此目的类型,将在代理选择器上调用 ISerializable.GetObjectData。
澳门葡京备用网址 95假定没有代理选拔器或有却不处理此类型,将检查是否利用 塞里alizable 属性对指标开始展览标记。要是未标记,将会掀起 SerializationException。
澳门葡京备用网址 96一经目的已被正确标记,将检核查象是不是贯彻了 ISerializable。若是已兑现,将在目的上调用 GetObjectData。
澳门葡京备用网址 97设若目的未完成 Serializable,将利用暗中认可的体系化策略,对富有未标记为 NonSerialized 的字段都开始展览种类化。
澳门葡京备用网址 98版本控制
澳门葡京备用网址 99.NET 框架支持版本控制和并排执行,并且,假若类的接口保持一致,全数类均可跨版本工作。由于类别化涉及的是成员变量而非接口,所以,在向要跨版本体系化的类中添加成员变量,或从中删除变量时,应小心行事。尤其是对于未兑现 ISerializable 的类更应如此。若当前版本的情况发生了其余变动(例如添加成员变量、更改变量类型或改变变量名称),都表示一旦相同类型的现有对象是选用最初版本实行体系化的,则无从得逞对它们举办反连串化。
澳门葡京备用网址 100
澳门葡京备用网址 101若是目的的图景要求在差异版本间爆发变动,类的撰稿人能够有三种选用:
澳门葡京备用网址 102
澳门葡京备用网址 103兑现 ISerializable。那使您能够准确地决定体系化和反连串化进度,在反系列化进程中国中国科学技术大学学学地充裕和释疑以往景观。
澳门葡京备用网址 104选拔 Non塞里alized 属性标记不根本的积极分子变量。仅当预测类在区别版本间的变动较时辰,才可利用这些选项。例如,把四个新变量添加至类的较高版本后,能够将该变量标记为 Non塞里alized,以管教该类与早期版本保持十分。
澳门葡京备用网址 105系列化规则
澳门葡京备用网址 106鉴于类编写翻译后便无计可施连串化,所以在设计新类时应考虑系列化。必要考虑的题材有:是不是必须跨应用程序域来发送此类?是不是要远程应用此类?用户将怎么样行使此类?可能他们会从自小编的类中派生出1个亟待种类化的新类。只要有那种恐怕性,就应将类标志为可连串化。除下列意况以外,最好将全部类都标志为可种类化:
澳门葡京备用网址 107
澳门葡京备用网址 108具有的类都永远也不会当先应用程序域。若是有些类不要求类别化但要求跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
澳门葡京备用网址 109类存款和储蓄仅适用于其日前实例的十三分规指针。例如,如若有个别类富含非受控的内部存款和储蓄器或文件句柄,请保管将那些字段标记为 NonSerialized 或根本不系列化此类。
澳门葡京备用网址 110一些数据成员包罗敏感音讯。在那种景观下,建议落实 ISerializable 并仅连串化所供给的字段。 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website