种类化和反连串化,MVC之类别化

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

 

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

using System.Runtime.Serialization.Formatters.Binary;

 

上面的代码将指标Person进行体系化并储存到三个文本中

亚洲必赢官网 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

 

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

亚洲必赢官网 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 框架提供的可信的连串化学工业机械制,
并珍视介绍使您能够依照必要自定义连串化进程的片段重点功用。

从头到尾存款和储蓄
 
 大家日常供给将对象的字段值保存到磁盘中,并在事后检索此数额。即便不利用种类化也能不负众望那项工作,但那种艺术一般很麻烦而且便于出错,并且在供给跟踪
对象的层次结构时,会变得愈加复杂。能够想像一下编写制定包蕴大批量对象的大型业务应用程序的情景,程序员不得不为每3个指标编排代码,以便将字段和质量保存
至磁盘以及从磁盘还原那么些字段和总体性。类别化提供了轻松达成这些目的的马上方法。
亚洲必赢官网 10
 
 公共语言运营时 (CLKoleos) 管理对象在内部存款和储蓄器中的分布,.NET 框架则经过运用反射提供自动的类别化学工业机械制。对象类别化后,类的称谓、程序集以及类实例
的具备数据成员均被写入存款和储蓄媒体中。对象经常用成员变量来存储对此外实例的引用。类系列化后,连串化引擎将跟踪全部已体系化的引用对象,以确认保障同等对象不
被类别化多次。.NET 框架所提供的体系化种类布局得以自行正确处理对象图表和循环引用。对目的图表的绝无仅有须要是,由正在进展体系化的目的所引用的全部对象都必须标记为 Serializable(请参阅基本连串化)。不然,当种类化程序试图类别化未标记的目的时将会出现非凡。
亚洲必赢官网 11
  当反类别化已连串化的类时,将再次创设该类,并自行回复全数数据成员的值。

按值封送
 
 对象仅在创设对象的接纳程序域中有效。除非对象是从 马尔斯halByRefObject 派生获得或标志为 Serializable,不然,任何
将对象作为参数字传送递或将其作为结果重回的尝试都将失败。假设指标标记为 塞里alizable,则该目的将被自动连串化,并从3个行使程序域传输至另
多个接纳程序域,然后开始展览反类别化,从而在其次个利用程序域中发出出该对象的3个可相信副本。此进程一般号称按值封送。
亚洲必赢官网 12
 
 如若目的是从 马尔斯halByRefObject 派生得到,则从叁个使用程序域传递至另1个使用程序域的是目的引用,而不是目的自笔者。也足以将
从 MarshalByRefObject 派生获得的靶子标记为 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

  本例使用二进制格式化程序进行连串化。您只需创造3个要运用的流和格式化程序的实例,然后调用格式化程序的 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 平台上海展览中心开反连串化的靶子,此格式化程序无疑是3个好好工具。要求小心的是,对目的举行反系列化时
并不调用构造函数。对反体系化添加那项约束,是由于质量方面包车型大巴设想。然而,这违背了指标编写者平常使用的有个别运营时约定,因而,开发职员在将对象标记为可
体系化时,应确认保证考虑了这一出奇约定。
亚洲必赢官网 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 }

  使用连串化属性分外便于,可是它存在上述的一部分限量。有关何时标记类以拓展类别化(因为类编写翻译后就不可能再系列化),请参考有关申明(请参阅下边包车型客车系列化规则)。

 

选拔性体系化
 
 类常常包涵不应被类别化的字段。例如,假诺有个别类用二个分子变量来存款和储蓄线程 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

 

自定义系列化
 
 能够由此在指标上完结 I塞里alizable 接口来自定义体系化进度。这一意义在反类别化后成员变量的值失效时尤其有用,可是需求为变量提供值
以重建对象的总体气象。要贯彻 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 的成员变量。假如基对象实现了 I塞里alizable,则派生类应调用其基对象
的 GetObjectData 方法。
亚洲必赢官网 27
 
 需求强调的是,将 ISerializable 添加至某些类时,要求同时落实 GetObjectData 以及卓殊的构造函数。假如贫乏 GetObjectData,编写翻译器将产生警告。可是,由于不可能强制完结构造函数,所以,缺乏构造函数时不会生出警告。若是在并未构造函数的情状下尝
试反连串化某些类,将会出现卓殊。在去掉潜在安全性和版本控制难题等方面,当前布置优化 SetObjectData 方法。例如,如若将 SetObjectData 方法定义为有个别接口的一有的,则此格局必须是公私艺术,那使得用户只好编写代码来严防频仍调
用 SetObjectData 方法。能够想像,如若有些对象正在举办某个操作,而有个别恶意应用程序却调用此指标的 SetObjectData 方
法,将会挑起局地暧昧的分神。
亚洲必赢官网 28
  在反系列化进程中,使用出于此指标而提供的构造函数将 SerializationInfo 传递给类。对象反类别化时,对构造函数的其他可知性约束都将被忽视,由此,能够将类标志为 public、protected、internal 或 private。3个科学的法子是,在类未封装的动静下,将构造函数标记为 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,则反体系化整个对象图表后,将自行调用 On塞里alization 方
法。此时,引用的全体子对象均已完全苏醒。有个别类不应用上述事件侦听器,很难对它们实行反种类化,散列表正是2个特出的例证。在反类别化进度中摸索关键字/值对至极简单,可是,由于不可能确认保障从散列表派生出的类已反类别化,所以把这几个目的添加回散列表时会产出局地题材。因而,提出最近绝不在散列表上调用方法。
亚洲必赢官网 33
系列化进度的步骤
  在格式化程序上调用 Serialize 方法时,对象体系化依照以下规则实行:
亚洲必赢官网 34
  检查格式化程序是不是有代理选拔器。假若有,检查代理选取器是或不是处理钦命项目标靶子。若是采纳器处理此目的类型,将在代理选择器上调用 ISerializable.GetObjectData。
  假若没有代理选用器或有却不处理此类型,将检查是否采纳 Serializable 属性对指标开始展览标记。即便未标记,将会引发 SerializationException。
  假使目的已被科学标记,将检查对象是或不是得以实现了 ISerializable。如若已落到实处,将在指标上调用 GetObjectData。
  假设指标未达成 塞里alizable,将应用默许的系列化策略,对全部未标记为 NonSerialized 的字段都开始展览体系化。
  版本控制
 
 .NET 框架补助版本控制和并排执行,并且,假若类的接口保持一致,全部类均可跨版本工作。由于类别化涉及的是成员变量而非接口,所以,在向要跨版本
系列化的类中添加成员变量,或从中删除变量时,应审慎行事。特别是对此未达成 ISerializable 的类更应这么。若当前版本的情况发生了任何变
化(例如添加成员变量、更改变量类型或改动变量名称),都代表一旦同样档次的现有对象是行使最初版本进行连串化的,则无法成功对它们举行反系列化。
亚洲必赢官网 35
  假使指标的气象供给在不一样版本间产生变动,类的撰稿人能够有三种接纳:
亚洲必赢官网 36
  达成 I塞里alizable。那使你能够规范地控制连串化和反连串化进度,在反种类化进度中正确地拉长和释疑现在处境。
  使用 NonSerialized 属性标记不重庆大学的积极分子变量。仅当预测类在差别版本间的更动较小时,才可应用那个选项。例如,把四个新变量添加至类的较高版本后,能够将该变量标记为 NonSerialized,以确认保障该类与中期版本保持包容。

体系化规则
 
 由于类编写翻译后便不或许种类化,所以在规划新类时应考虑类别化。须要考虑的标题有:是或不是必须跨应用程序域来发送此类?是不是要远程应用此类?用户将怎么样使用此
类?恐怕他们会从自家的类中派生出3个索要连串化的新类。只要有那种可能性,就应将类标志为可连串化。除下列境况以外,最棒将全数类都标志为可体系化:
亚洲必赢官网 37
  全部的类都永远也不会超越应用程序域。就算某些类不供给系列化但要求跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
  类存款和储蓄仅适用于其近日实例的出格指针。例如,就算有些类富含非受控的内部存款和储蓄器或文件句柄,请保管将这几个字段标记为 NonSerialized 或根本不类别化此类。
  有些数据成员包罗敏感音讯。在这种状态下,提议落到实处 ISerializable 并仅种类化所须要的字段。 

转自:

1.AdminUserInfo.cs

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

为啥要使用体系化?

[Serializable]队列化类——System.SerializableAttribute

一齐复制二个引用类型对象重要有三种办法:

1.额外添加二个构造函数,入参为待复制对象(如若字段为引用类型,要求一连添加构造函数,那样情状会变的12分复杂。)

    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.选拔反射(测试了3个网上的接口可用,但是对质量杀伤和类别化反种类化十分,而且对代码混淆有一定影响。 
 

最要紧的八个原因是:

串行化是指储存和取得磁盘文件、内部存款和储蓄器或别的地点中的对象。在串行化时,全部的实例数据都保存到存款和储蓄介质上,在打消串行化时,对象会被恢复生机,且不可能与其原实例分歧开来。

1.     
将对象的事态保存在储存媒体中以便能够在后头再一次创制出完全相同的副本;

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

2.     
按值将目标从3个施用程序域发送至另2个施用程序域。

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

比如说,体系化可用以在 ASP.NET
中保留会话状态,以及将对象复制到 Windows
窗体的剪贴板中。

例:

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

 

本文简要介绍了 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进行系列化并储存到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();

1.     
先将对象的公共字段和个体字段以及类的名目(包含类所在的程序集)转换为字节流,

 

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

种类化和反连串化,MVC之类别化。下一场再举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
框架提供的笃定的连串化学工业机械制,并首要介绍使你能够依照须要自定义连串化进程的某个第2作用。

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

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

贰 、         持久存款和储蓄

作者们平时须要将对象的字段值保存到磁盘中,并在其后检索此数据。

尽管不选拔体系化也能形成那项工作,但那种格局一般很麻烦而且便于出错,并且在急需跟踪对象的层次结构时,会变得越发复杂。

能够想象一下编辑包罗多量指标的巨型业务应用程序的地方,程序员不得不为每三个对象编排代码,以便将字段和质量保存至磁盘以及从磁盘还原那一个字段和质量。

系列化提供了轻松完结那几个指标的飞跃方法。

国有语言运转时 (CL奇骏)
管理对象在内部存款和储蓄器中的分布,.NET
框架则透过选拔反射提供自动的连串化学工业机械制。

目的连串化后,类的称呼、程序集以及类实例的享有数据成员均被写入仓库储存媒体[本文中的存款和储蓄媒体是如何?xml?]中。

对象一般用成员变量来储存对任何实例的引用。类系列化后,种类化引擎将跟踪全体已体系化的引用对象,以保障同等对象不被体系化多次[类别化是指向对象的?那岂不是三个先后会须要广大的类别化?]。

.NET
框架所提供的连串化系列布局能够活动正确处理对象图表和循环引用。

对目的图表[如何是指标图表?]的唯一须求是,由正在进展连串化的靶子所引述的富有指标都必须标记为
Serializable(请参阅主干系列化)。不然,当体系化程序试图系列化未标记的指标时将会出现格外。

当反连串化已系列化的类时,将再一次创制该类,并活动回复全数数据成员的值。

 Serializable在C#中的功效.NET 中的对象体系化
亚洲必赢官网 38
亚洲必赢官网 39简介
亚洲必赢官网 40类别化是指将对象实例的动静存款和储蓄到存款和储蓄媒体的长河。在此进度中,先将目的的共用字段和个人字段以及类的名称(包含类所在的程序集)转换为字节流,然后再把字节流写入数据流。在紧接着对指标进行反连串化时,将开创出与原对象完全相同的副本。
亚洲必赢官网 41
亚洲必赢官网 42在面向对象的环境中落实类别化学工业机械制时,必须在易用性和灵活性之间进行部分权衡。只要你对此进程有丰富的控制能力,就足以使该进度在相当大程度上活动举办。例如,简单的二进制种类化无法知足急需,或许,由于特定原因须要规定类中那三个字段需求连串化。以下各部分将追究 .NET 框架提供的可靠的种类化学工业机械制,并紧要介绍使您能够依照必要自定义连串化进度的片段要害成效。
亚洲必赢官网 43
亚洲必赢官网 44从头到尾存款和储蓄
亚洲必赢官网 45大家平日索要将目的的字段值保存到磁盘中,并在此后检索此数额。即便不应用类别化也能到位那项工作,但那种措施一般很麻烦而且便于出错,并且在急需跟踪对象的层次结构时,会变得尤其复杂。能够设想一下编写制定包蕴大批量指标的特大型业务应用程序的状态,程序员不得不为每一个对象编排代码,以便将字段和属性保存至磁盘以及从磁盘还原这一个字段和品质。系列化提供了轻松实现那么些目标的连忙方法。
亚洲必赢官网 46
亚洲必赢官网 47公物语言运维时 (CL福特Explorer) 管理对象在内存中的分布,.NET 框架则透过利用反射提供自动的类别化学工业机械制。对象系列化后,类的称号、程序集以及类实例的享有数据成员均被写入存款和储蓄媒体中。对象平时用成员变量来储存对任何实例的引用。类体系化后,类别化引擎将跟踪全体已系列化的引用对象,以管教同等对象不被系列化数次。.NET 框架所提供的系列化种类布局得以自动正确处理对象图表和循环引用。对指标图表的唯一需求是,由正在拓展连串化的靶子所引用的拥有目的都必须标记为 Serializable(请参阅基本系列化)。不然,当种类化程序试图体系化未标记的靶马时将会现身万分。
亚洲必赢官网 48
亚洲必赢官网 49当反类别化已体系化的类时,将重新创设该类,并自动回复全体数据成员的值。
亚洲必赢官网 50
亚洲必赢官网 51按值封送
亚洲必赢官网 52目的仅在成立对象的使用程序域中央银一蹴而就。除非对象是从 马尔斯halByRefObject 派生得到或标志为 Serializable,不然,任何将目的作为参数字传送递或将其看作结果重回的品味都将破产。假如指标标记为 Serializable,则该指标将被活动种类化,并从1个采纳程序域传输至另叁个用到程序域,然后开始展览反系列化,从而在第三个应用程序域中生出出该目的的叁个确切副本。此进度一般号称按值封送。
亚洲必赢官网 53
亚洲必赢官网 54只要指标是从 马尔斯halByRefObject 派生获得,则从1个用到程序域传递至另贰个使用程序域的是指标引用,而不是目的自笔者。也足以将从 马尔斯halByRefObject 派生得到的对象标记为 Serializable。远程应用此指标时,负责实行系列化并已先期计划为 SurrogateSelector 的格式化程序将控制系列化进程,并用三个代理替换全体从 马尔斯halByRefObject 派生获得的对象。假诺没有事先布置为 SurrogateSelector,类别化体系布局将服从上面包车型地铁正儿八经体系化规则(请参阅种类化进度的步调)。
亚洲必赢官网 55
亚洲必赢官网 56着力种类化
亚洲必赢官网 57要使叁个类可体系化,最简易的不二法门是行使 Serializable 属性对它举行标记,如下所示:
亚洲必赢官网 58

三 、        按值封送

对象仅在创制对象的施用程序域中央银一蹴而就。除非对象是从 MarshalByRefObject
派生获得或标志为 Serializable,不然,任何将对象作为参数字传送递或将其作为结果回到的尝尝都将破产。

借使指标标记为 Serializable[什么样标记为Serializable],则该对象将被活动类别化,并从一个利用程序域传输至另三个选用程序域,然后举办反连串化,从而在第贰个应用程序域中产生出该指标的2个准确无误副本。此进程一般称为按值封送

如果指标是从 MarshalByRefObject
派生得到,则从一个选择程序域传递至另二个施用程序域的是目的引用,而不是目的自作者。

也能够将从 MarshalByRefObject 派生获得的靶子标记为 Serializable

长途应用此指标时,负责进行体系化并已事先布署为 SurrogateSelector
的格式化程序将决定种类化进程,并用3个代理替换全体从 MarshalByRefObject
派生获得的靶子。即便没有先行布署为 SurrogateSelector,系列化系列布局将坚守上边包车型大巴标准体系化规则(请参阅类别化进度的步调)。

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

④ 、        基本类别化

亚洲必赢官网 ,要使三个类可连串化,最简便的方法是行使 Serializable 属性[缘何webservice中没有标记Serializable?]

对它实行标记,如下所示:

[Serializable]

 public class MyObject {

  public int n1 = 0;

  public int n2 = 0;

  public String str = null;

}

以下代码片段表达了哪些将该类的叁个实例系列化为3个文本[咱俩不供给用手写那个代码吧?]:

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是还是不是正是本文所说的蕴藏媒体?]。

将对象还原到它原先的境况也分外不难。

第3,创制格式化程序和流以实行读取,

然后让格式化程序对目的举办反系列化。

以下代码片段表达了什么开始展览此操作。

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
派生出3个新的类,则那个新的类也不可能不运用该属性举办标记,不然将不可能类别化。[如果Serializable
属性不可能三番伍回,为啥webservice类中从不设置Serializable 属性?]

譬如说,假如打算类别化以下类实例,将会突显3个 SerializationException,说明 MyStuff
类型未标记为可系列化。

public class MyStuff : MyObject

{

  public int n3;

}

使用类别化属性卓殊便利,然则它存在上述的某些限制。

至于什么日期标记类以进行系列化(因为类编写翻译后就无法再类别化),请参见有关证实(请参阅上面包车型大巴体系化规则)。

亚洲必赢官网 59以下代码片段表明了怎么样将此类的三个实例种类化为二个文件:
亚洲必赢官网 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
方法以及3个异样的构造函数[不是反体系化的时候,不调用构造函数吗?],在反体系化对象时要用到此构造函数。

以下代码示例表明了什么在前一部分中涉及的 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。

1个不错的措施是,在类未封装的场所下,将构造函数标记为 protect。如若类已打包,则应标记为
private。要东山再起对象的气象,只需采用连串化时采纳的名称,从 SerializationInfo
中检索变量的值。尽管基类完成了 ISerializable,则应调用基类的构造函数,以使基础对象能够还原其变量。

若果从落到实处了 ISerializable
的类派生出1个新的类,则只要新的类中包蕴其余供给连串化的变量,就非得同时落到实处构造函数以及
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
方法。此时,引用的全部子对象均已完全复苏。

稍微类不选取上述事件侦听器,很难对它们举办反系列化,散列表[怎样是散列表?]就是二个非凡的例证。

在反系列化进程中搜索关键字/值对非常不难,不过,由于不恐怕确定保证从散列表派生出的类已反系列化,所以把那么些目的添加回散列表时汇合世部分问题。因而,提出方今不要在散列表上调用方法。

亚洲必赢官网 61本例使用二进制格式化程序进行类别化。您只需创制1个要选用的流和格式化程序的实例,然后调用格式化程序的 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
    属性标记不根本的成员变量。仅当预测类在差别版本间的变动较时辰,才可应用这些选项。例如,把三个新变量添加至类的较高版本后,能够将该变量标记为
    NonSerialized,以管教该类与早期版本保持万分[连串化对象中包括NonSerialized标记,是或不是有隐患?]。

亚洲必赢官网 65上边所利用的 BinaryFormatter 作用很高,能生成尤其严厉的字节流。全数应用此格式化程序连串化的指标也可选取它实行反种类化,对于连串化将在 .NET 平台上拓展反连串化的靶子,此格式化程序无疑是二个突出工具。供给留意的是,对目标开始展览反系列化时并不调用构造函数。对反种类化添加那项约束,是由于质量方面包车型客车考虑。不过,那违反了指标编写者常常选取的片段运行时约定,因而,开发职员在将指标标记为可连串化时,应保障考虑了这一特种约定。
亚洲必赢官网 66
亚洲必赢官网 67万一要求具有可移植性,请使用 SoapFormatter。所要做的转移只是将以上代码中的格式化程序换到 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于地点运用的演示,该格式化程序将扭转以下结果。
亚洲必赢官网 68

九 、        种类化规则

鉴于类编写翻译后便无法类别化[种类化的火候是何许时候,由什么人(CL讴歌ZDX还是其余)来兑现种类化?凡种类化的机会是几时,由什么人来达成?那么,webservice是如几时候种类化,哪天反系列化?][类编译后便不能够再类别化?是或不是类和指标都得以连串化?][体系化是或不是和原数据表单联系很密切?],所以在筹划新类时应考虑体系化。

亟待考虑的难点有:

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

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

3.      用户将什么使用此类?

唯恐他们会从自家的类中派生出1个亟需种类化的新类。只要有这种大概,就应将类标志为可系列化。除下列意况以外,最棒将全数类都标志为可种类化:

  • 不无的类都永远也不会超越应用程序域。假诺有个别类不要求系列化但需求跨越应用程序域,请从
    MarshalByRefObject
    派生此类。
  • 类存款和储蓄仅适用于其如今实例的特种指针。例如,固然有些类富含非受控的内部存款和储蓄器或文件句柄,请确认保证将那几个字段标记为
    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宝马7系照旧别的)来达成类别化?凡系列化的机会是什么样时候,由何人来完结?那么,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类日常包罗不应被连串化的字段。例如,倘使有个别类用一个分子变量来存款和储蓄线程 ID。当此类被反类别化时,连串化此类时所蕴藏的 ID 对应的线程恐怕不再运维,所以对这些值举行连串化没有意义。能够透过动用 NonSerialized 属性标记成员变量来预防它们被类别化,如下所示:
亚洲必赢官网 75

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

亚洲必赢官网 76自定义体系化
亚洲必赢官网 77能够因而在指标上落到实处 ISerializable 接口来自定义体系化进度。这一效益在反体系化后成员变量的值失效时越发有用,可是急需为变量提供值以重建对象的完全气象。要完毕 I塞里alizable,需求贯彻 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。2个毋庸置疑的不二法门是,在类未封装的状态下,将构造函数标记为 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 方法。此时,引用的全部子对象均已通通苏醒。某个类不使用上述事件侦听器,很难对它们进行反种类化,散列表便是叁个典型的例证。在反类别化进度中寻找关键字/值对万分简单,然而,由于不能保险从散列表派生出的类已反系列化,所以把那一个指标添加回散列表时会冒出有的难题。由此,建议如今并非在散列表上调用方法。
亚洲必赢官网 90
亚洲必赢官网 91连串化进程的步子
亚洲必赢官网 92在格式化程序上调用 Serialize 方法时,对象系列化依据以下规则实行:
亚洲必赢官网 93
亚洲必赢官网 94自作者批评格式化程序是还是不是有代理选择器。如若有,检查代理选择器是或不是处理钦点项指标目的。假设采用器处理此指标类型,将在代理选择器上调用 ISerializable.GetObjectData。
亚洲必赢官网 95若是没有代理采用器或有却不处理此类型,将检查是否利用 Serializable 属性对目的开始展览标记。倘诺未标记,将会掀起 SerializationException。
亚洲必赢官网 96比方目的已被科学标记,将检核对象是还是不是达成了 ISerializable。要是已兑现,将在指标上调用 GetObjectData。
亚洲必赢官网 97只要指标未兑现 塞里alizable,将运用暗中同意的体系化策略,对负有未标记为 NonSerialized 的字段都实行种类化。
亚洲必赢官网 98版本控制
亚洲必赢官网 99.NET 框架支持版本控制和并排执行,并且,假使类的接口保持一致,全数类均可跨版本工作。由于类别化涉及的是成员变量而非接口,所以,在向要跨版本系列化的类中添加成员变量,或从中删除变量时,应谨慎行事。越发是对于未落到实处 I塞里alizable 的类更应如此。若当前版本的景况发生了其余变化(例如添加成员变量、更改变量类型或转移变量名称),都意味如若一致类其余现有对象是行使最初版本实行连串化的,则不恐怕成功对它们举行反种类化。
亚洲必赢官网 100
亚洲必赢官网 101比方指标的气象供给在不相同版本间爆发改变,类的小编能够有二种接纳:
亚洲必赢官网 102
亚洲必赢官网 103兑现 ISerializable。那使你能够准确地决定系列化和反种类化进度,在反体系化进度中正确地加上和表明今后状态。
亚洲必赢官网 104选用 NonSerialized 属性标记不根本的成员变量。仅当预测类在差异版本间的生成较小时,才可使用那一个选项。例如,把二个新变量添加至类的较高版本后,能够将该变量标记为 NonSerialized,以保证该类与最初版本保持极度。
亚洲必赢官网 105体系化规则
亚洲必赢官网 106是因为类编写翻译后便无计可施系列化,所以在筹划新类时应考虑种类化。要求考虑的难题有:是或不是必须跨应用程序域来发送此类?是还是不是要远程应用此类?用户将何以采用此类?可能他们会从本身的类中派生出一个亟需类别化的新类。只要有这种恐怕,就应将类标志为可连串化。除下列情形以外,最佳将全部类都标志为可连串化:
亚洲必赢官网 107
亚洲必赢官网 108负有的类都永远也不会超越应用程序域。如果有个别类不须求类别化但要求跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
亚洲必赢官网 109类存款和储蓄仅适用于其日前实例的12分指针。例如,要是有些类富含非受控的内部存款和储蓄器或文件句柄,请确认保证将那一个字段标记为 NonSerialized 或根本不连串化此类。
亚洲必赢官网 110好几数据成员包涵敏感信息。在那种情况下,提议落到实处 ISerializable 并仅连串化所必要的字段。 

网站地图xml地图