引用类型对象的深拷贝,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

 

下边来看三个小例子,首先要添加命名空间

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 框架提供的笃定的系列化学工业机械制,
并注重介绍使你能够依照供给自定义体系化进度的一些首要意义。

从头到尾存款和储蓄
 
 大家平常索要将指标的字段值保存到磁盘中,并在后头检索此数量。即使不应用系列化也能不辱职分这项工作,但那种措施一般很麻烦而且简单失误,并且在急需跟踪
对象的层次结构时,会变得更为复杂。能够设想一下编纂包罗大批量指标的特大型业务应用程序的情事,程序员不得不为每三个对象编排代码,以便将字段和属性保存
至磁盘以及从磁盘还原这一个字段和性能。体系化提供了轻松达成那几个指标的火速方法。
美高梅开户网址 10
 
 公共语言运营时 (CL福睿斯) 管理对象在内存中的分布,.NET 框架则透过动用反射提供自动的体系化机制。对象连串化后,类的称呼、程序集以及类实例
的享有数据成员均被写入存款和储蓄媒体中。对象日常用成员变量来储存对任何实例的引用。类类别化后,体系化引擎将跟踪全数已体系化的引用对象,以保证同等对象不
被类别化数次。.NET 框架所提供的种类化体系布局得以自动正确处理对象图表和循环引用。对目的图表的绝无仅有供给是,由正在拓展系列化的靶子所引用的全部对象都必须标记为 Serializable(请参阅基本连串化)。不然,当系列化程序试图种类化未标记的靶子时将会出现很是。
美高梅开户网址 11
  当反类别化已序列化的类时,将再也创建该类,并自动回复全数数据成员的值。

按值封送
 
 对象仅在成立对象的应用程序域中立竿见影。除非对象是从 马尔斯halByRefObject 派生获得或标志为 Serializable,不然,任何
将对象作为参数字传送递或将其看成结果回到的品尝都将战败。若是指标标记为 Serializable,则该目的将被电动系列化,并从3个选拔程序域传输至另
1个施用程序域,然后进行反类别化,从而在其次个利用程序域中生出出该对象的二个规范副本。此进度一般号称按值封送。
美高梅开户网址 12
 
 假设指标是从 马尔斯halByRefObject 派生获得,则从一个选取程序域传递至另1个采用程序域的是目的引用,而不是目的自笔者。也足以将
从 马尔斯halByRefObject 派生得到的对象标记为 Serializable。远程应用此目的时,负责进行连串化并已先行布置为 SurrogateSelector 的格式化程序将决定种类化进程,并用八个代理替换全体从 马尔斯halByRefObject 派生得到的对
象。要是没有事先安插为 SurrogateSelector,类别化种类布局将信守上边包车型客车正儿八经连串化规则(请参阅类别化进程的步子)。

 

主题连串化
  要使二个类可连串化,最简易的法门是使用 塞里alizable 属性对它举办标记,如下所示:

美高梅开户网址 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

  以下代码片段表明了如何将该类的一个实例种类化为一个文件:

美高梅开户网址 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

  本例使用二进制格式化程序实行连串化。您只需创设2个要利用的流和格式化程序的实例,然后调用格式化程序的 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 平台上进展反体系化的靶子,此格式化程序无疑是一个精美术工作具。需求专注的是,对目标进行反类别化时
并不调用构造函数。对反连串化添加那项约束,是出于质量方面包车型地铁设想。但是,那违背了目的编写者平常选拔的局地周转时约定,因而,开发人士在将对象标记为可
种类化时,应确定保障考虑了这一分歧日常约定。
美高梅开户网址 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 }

  使用体系化属性13分有利,不过它存在上述的部分限制。有关哪一天标记类以进行连串化(因为类编写翻译后就不恐怕再连串化),请参见有关表明(请参阅上面包车型大巴系列化规则)。

 

选取性体系化
 
 类平日包罗不应被连串化的字段。例如,借使有个别类用一个成员变量来存款和储蓄线程 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 类上落到实处 I塞里alizable。

美高梅开户网址 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 时,必要填写方法调用中提供的 塞里alizationInfo 对象。只需按名称/值
对的款式丰裕将要体系化的变量。其名目能够是任何公文。只要已连串化的数据可以在反体系化进度中还原对象,便足以自由选择添加
至 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,则反种类化整个对象图表后,将机关调用 On塞里alization 方
法。此时,引用的全数子对象均已通通复苏。有个别类不接纳上述事件侦听器,很难对它们进行反系列化,散列表正是一个优秀的例子。在反连串化进程中找寻关键字/值对格外简单,可是,由于不可能担保从散列表派生出的类已反系列化,所以把这几个目标添加回散列表时会油可是生部分标题。因而,提议近来不用在散列表上调用方法。
美高梅开户网址 33
种类化进程的步子
  在格式化程序上调用 Serialize 方法时,对象连串化依照以下规则举办:
美高梅开户网址 34
  检查格式化程序是或不是有代理选择器。若是有,检查代理选拔器是还是不是处理钦命项指标指标。如若采纳器处理此指标类型,将在代理采纳器上调用 ISerializable.GetObjectData。
  假若没有代理选用器或有却不处理此类型,将检查是否利用 Serializable 属性对指标开始展览标记。如若未标记,将会掀起 SerializationException。
  若是目的已被科学标记,将检查对象是还是不是实现了 I塞里alizable。假如已兑现,将在指标上调用 GetObjectData。
  如若目的未落实 Serializable,将利用暗中同意的系列化策略,对具有未标记为 NonSerialized 的字段都实行类别化。
  版本控制
 
 .NET 框架补助版本控制和并排执行,并且,假若类的接口保持一致,全部类均可跨版本工作。由于连串化涉及的是成员变量而非接口,所以,在向要跨版本
种类化的类中添加成员变量,或从中删除变量时,应严刻行事。特别是对于未落到实处 ISerializable 的类更应如此。若当前版本的气象发生了别样变
化(例如添加成员变量、更改变量类型或改变变量名称),都表示一旦一致类型的幸存对象是使用最初版本实行连串化的,则无从得逞对它们实行反类别化。
美高梅开户网址 35
  如若目的的状态必要在不相同版本间产生变更,类的撰稿人能够有二种选择:
美高梅开户网址 36
  达成 ISerializable。那使您能够确切地决定系列化和反连串化进度,在反类别化进程中国科高校学地抬高和分解今后景况。
  使用 NonSerialized 属性标记不主要的分子变量。仅当预测类在差别版本间的更动较小时,才可采用那一个选项。例如,把三个新变量添加至类的较高版本后,能够将该变量标记为 NonSerialized,以保险该类与最初版本保持包容。

种类化规则
 
 由于类编写翻译后便无计可施连串化,所以在筹划新类时应考虑种类化。供给考虑的题材有:是还是不是必须跨应用程序域来发送此类?是或不是要远程应用此类?用户将怎么着采纳此
类?恐怕他们会从作者的类中派生出1个必要连串化的新类。只要有那种大概,就应将类标志为可连串化。除下列情形以外,最棒将全部类都标志为可体系化:
美高梅开户网址 37
  全数的类都永远也不会超越应用程序域。尽管某些类不需要系列化但必要跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
  类存款和储蓄仅适用于其眼下实例的相当指针。例如,假若有个别类富含非受控的内部存款和储蓄器或文件句柄,请确定保障将那一个字段标记为 Non塞里alized 或根本不种类化此类。
  有些数据成员包蕴敏感新闻。在那种气象下,建议落到实处 ISerializable 并仅连串化所要求的字段。 

转自:

1.AdminUserInfo.cs

值类型直接存储对象,而引用类型存款和储蓄对象的地方,在对引用类型举办复制的时候,也只是复制对象的地方。

缘何要选取体系化?

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

统统复制二个引用类型对象重要有两种方法:

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>();
    }
}

引用类型对象的深拷贝,MVC之系列化。3.行使反射(测试了一个网上的接口可用,但是对质量杀伤和连串化反连串化万分,而且对代码混淆有肯定影响。 
 

最重点的多个原因是:

串行化是指储存和收获磁盘文件、内部存款和储蓄器或别的地点中的对象。在串行化时,全部的实例数据都保留到存款和储蓄介质上,在撤消串行化时,对象会被还原,且无法与其原实例区别开来。

1.     
将目的的图景保存在储存媒体中以便能够在后来再也创建出完全相同的副本;

只需给类添加塞里alizable属性,就能够达成串行化实例的成员。

2.     
按值将指标从二个采纳程序域发送至另三个选拔程序域。

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

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

例:

它还可用以按值将对象从3个行使程序域远程传递至另贰个行使程序域。

 

正文简要介绍了 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.      然后再把字节流写入数据流。

下一场再举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;
}

二 、         持久存款和储蓄

大家日常索要将目的的字段值保存到磁盘中,并在事后检索此数额。

固然不利用体系化也能成就那项工作,但那种办法一般很麻烦而且便于出错,并且在需求跟踪对象的层次结构时,会变得更其复杂。

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

类别化提供了轻松达成这么些指标的高效方法。

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

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

指标一般用成员变量来囤积对别的实例的引用。类连串化后,种类化引擎将跟踪全数已连串化的引用对象,以担保同等对象不被体系化多次[类别化是本着对象的?这岂不是一个程序会须要过多的连串化?]。

.NET
框架所提供的系列化种类布局得以活动正确处理对象图表和循环引用。

对指标图表[什么是指标图表?]的唯一需求是,由正在展开体系化的对象所引述的具有指标都必须标记为
Serializable(请参阅大旨种类化)。不然,当连串化程序试图系列化未标记的靶鸡时将会出现相当。

当反系列化已连串化的类时,将再也创造该类,并自动苏醒全数数据成员的值。

 Serializable在C#中的功能.NET 中的对象类别化
美高梅开户网址 38
美高梅开户网址 39简介
美高梅开户网址 40连串化是指将对象实例的事态存款和储蓄到存储媒体的经过。在此进度中,先将目标的国有字段和民用字段以及类的称呼(包罗类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对目的开始展览反体系化时,将创建出与原对象完全相同的副本。
美高梅开户网址 41
美高梅开户网址 42在面向对象的条件中完成体系化学工业机械制时,必须在易用性和灵活性之间开始展览局地权衡。只要您对此进度有丰硕的控制能力,就可以使该进程在非常的大程度上电动进行。例如,简单的二进制连串化不能知足急需,或然,由于特定原因要求规定类中那多少个字段须要体系化。以下各部分将探索 .NET 框架提供的保障的种类化学工业机械制,一碗水端平点介绍使您可以根据必要自定义类别化进度的一对至关首要功用。
美高梅开户网址 43
美高梅开户网址 44慎始而敬终存储
美高梅开户网址 45大家常常须要将指标的字段值保存到磁盘中,并在今后检索此数量。就算不使用连串化也能连成一气那项工作,但那种办法一般很麻烦而且不难失误,并且在须要跟踪对象的层次结构时,会变得进一步复杂。能够设想一下编纂包涵大批量对象的重型业务应用程序的情况,程序员不得不为每一个目的编排代码,以便将字段和性子保存至磁盘以及从磁盘还原那一个字段和属性。种类化提供了轻松达成那么些目的的敏捷方法。
美高梅开户网址 46
美高梅开户网址 47集体语言运维时 (CLRubicon) 管理对象在内部存款和储蓄器中的分布,.NET 框架则透过应用反射提供自动的体系化学工业机械制。对象类别化后,类的名称、程序集以及类实例的持有数据成员均被写入存款和储蓄媒体中。对象日常用成员变量来存款和储蓄对其他实例的引用。类序列化后,连串化引擎将跟踪全体已连串化的引用对象,以确定保障同等对象不被体系化多次。.NET 框架所提供的体系化类别布局能够自动正确处理对象图表和巡回引用。对指标图表的绝无仅有必要是,由正在开始展览类别化的靶子所引用的具有目的都无法不标记为 塞里alizable(请参阅基本系列化)。不然,当种类化程序试图连串化未标记的目的时将会出现极度。
美高梅开户网址 48
美高梅开户网址 49当反类别化已系列化的类时,将再次创立该类,并自行回复全部数据成员的值。
美高梅开户网址 50
美高梅开户网址 51按值封送
美高梅开户网址 52对象仅在创设对象的运用程序域中央银一蹴而就。除非对象是从 马尔斯halByRefObject 派生获得或标志为 Serializable,不然,任何将对象作为参数字传送递或将其视作结果回到的尝尝都将退步。如若指标标记为 塞里alizable,则该指标将被电动连串化,并从多少个施用程序域传输至另叁个运用程序域,然后实行反种类化,从而在其次个使用程序域中生出出该指标的3个准确无误副本。此进程一般称为按值封送。
美高梅开户网址 53
美高梅开户网址 54若果目的是从 MarshalByRefObject 派生得到,则从一个用到程序域传递至另3个用到程序域的是指标引用,而不是目的自作者。也能够将从 马尔斯halByRefObject 派生获得的指标标记为 Serializable。远程应用此目的时,负责举办类别化并已事先布置为 SurrogateSelector 的格式化程序将决定体系化进度,并用2个代理替换全数从 马尔斯halByRefObject 派生获得的靶子。假若没有优先安顿为 SurrogateSelector,连串化连串布局将信守下边包车型大巴科班类别化规则(请参阅体系化进度的步子)。
美高梅开户网址 55
美高梅开户网址 56着力类别化
美高梅开户网址 57要使2个类可连串化,最简易的主意是利用 Serializable 属性对它进行标记,如下所示:
美高梅开户网址 58

三 、        按值封送

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

比方指标标记为 Serializable[怎样标记为Serializable],则该对象将被电动体系化,并从2个接纳程序域传输至另三个用到程序域,然后进行反体系化,从而在其次个使用程序域中生出出该指标的2个纯粹副本。此进度一般称为按值封送

假定目的是从 MarshalByRefObject
派生获得,则从一个用到程序域传递至另2个用到程序域的是目标引用,而不是目的自笔者。

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

远程应用此目的时,负责举行系列化并已先行布署为 SurrogateSelector
的格式化程序将决定类别化进度,并用3个代理替换全部从 MarshalByRefObject
派生获得的目的。就算没有事先布署为 SurrogateSelector,种类化连串布局将服从下边包车型大巴科班连串化规则(请参阅种类化进程的手续)。

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

四 、        基本连串化

要使1个类可系列化,最不难易行的点子是使用 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();

本例使用二进制格式化程序实行连串化。

你只需创造1个要接纳的流和格式化程序的实例,然后调用格式化程序的 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
平台上进展反序列化的目的,此格式化程序无疑是2个好好工具。

必要专注的是,对指标开始展览反连串化时并不调用构造函数[不调用构造函数,会不会为编制程序带来影响,例如不可能在构造函数中添加逻辑?照旧,不必要关注构造函数,因为对象的变量足以申明对象的情景?]。对反系列化添加那项约束,是出于质量方面包车型客车设想[不调用构造函数?者对质量会有多大影响,这么说调用构造函数并不是全然没有要求?]。然而,那违背了对象编写者经常选取的一些周转时约定,因而,开发职员在将对象标记为可体系化时,应保障考虑了这一特种约定。

设若供给全体可移植性,请使用 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以下代码片段表明了怎样将该类的2个实例类别化为一个文件:
美高梅开户网址 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。

贰个正确的点子是,在类未封装的情况下,将构造函数标记为 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
方法。此时,引用的全体子对象均已完全恢复生机。

稍稍类不选用上述事件侦听器,很难对它们举行反系列化,散列表[何以是散列表?]便是八个卓越的例证。

在反种类化进程中追寻关键字/值对分外不难,可是,由于不或许确认保证从散列表派生出的类已反系列化,所以把这几个目的添加回散列表时会产出局地难题。由此,提出近日绝不在散列表上调用方法。

美高梅开户网址 61本例使用二进制格式化程序实行体系化。您只需成立3个要选用的流和格式化程序的实例,然后调用格式化程序的 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,而 塞里alize 和 Deserialize 调用不变。对于地方使用的示范,该格式化程序将转变以下结果。
美高梅开户网址 68

⑨ 、        连串化规则

出于类编写翻译后便无能为力系列化[连串化的时机是何等时候,由哪个人(CLRubicon依旧其余)来兑现类别化?凡系列化的机遇是何许时候,由什么人来完成?那么,webservice是哪一天连串化,哪天反系列化?][类编写翻译后便无能为力再体系化?是或不是类和对象都能够连串化?][种类化是或不是和原数据表单联系不粗大心?],所以在规划新类时应考虑系列化。

内需考虑的标题有:

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

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

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

或然他们会从本身的类中派生出叁个索要连串化的新类。只要有那种或然性,就应将类标志为可连串化。除下列景况以外,最棒将全数类都标志为可体系化:

  • 持有的类都永远也不会超过应用程序域。假设有个别类不需要体系化但须求跨越应用程序域,请从
    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:类别化的机会是如哪天候,由何人(CLHaval如故别的)来贯彻连串化?凡连串化的机遇是哪些时候,由什么人来落成?那么,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 派生出3个新的类,则那么些新的类也非得接纳该属性进行标记,不然将不只怕类别化。例如,倘使打算类别化以下类实例,将会呈现3个 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 接口来自定义类别化进程。这一功力在反连串化后成员变量的值失效时尤其有用,但是急需为变量提供值以重建对象的完整气象。要贯彻 ISerializable,须要贯彻 GetObjectData 方法以及3个特殊的构造函数,在反体系化对象时要用到此构造函数。以下代码示例表达了什么在前一部分中提到的 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。1个没错的措施是,在类未封装的景况下,将构造函数标记为 protect。要是类已打包,则应标记为 private。要过来对象的情况,只需采取系列化时选用的名称,从 SerializationInfo 中搜寻变量的值。要是基类实现了 I塞里alizable,则应调用基类的构造函数,以使基础对象可以还原其变量。
美高梅开户网址 84
美高梅开户网址 85万一从达成了 ISerializable 的类派生出3个新的类,则只要新的类中包蕴其他必要类别化的变量,就必须同时落到实处构造函数以及 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要是目的未完成 Serializable,将运用暗中同意的体系化策略,对具备未标记为 NonSerialized 的字段都开始展览体系化。
美高梅开户网址 98版本控制
美高梅开户网址 99.NET 框架帮忙版本控制和并排执行,并且,借使类的接口保持一致,全体类均可跨版本工作。由于种类化涉及的是成员变量而非接口,所以,在向要跨版本种类化的类中添加成员变量,或从中删除变量时,应严俊行事。越发是对此未实现 ISerializable 的类更应这么。若当前版本的意况产生了任何变更(例如添加成员变量、更改变量类型或改变变量名称),都表示一旦同样类型的并存对象是接纳最初版本实行类别化的,则不能够得逞对它们进行反种类化。
美高梅开户网址 100
美高梅开户网址 101只要目的的景况须要在分化版本间发生改变,类的撰稿人能够有三种选拔:
美高梅开户网址 102
美高梅开户网址 103兑现 ISerializable。那使您能够精确地控制种类化和反系列化进度,在反类别化进程中正确地加上和释疑将来情状。
美高梅开户网址 104选取 NonSerialized 属性标记不主要的积极分子变量。仅当预测类在分裂版本间的浮动较小时,才可应用这几个选项。例如,把三个新变量添加至类的较高版本后,能够将该变量标记为 NonSerialized,以确定保障该类与先前时代版本保持包容。
美高梅开户网址 105连串化规则
美高梅开户网址 106由于类编写翻译后便无法类别化,所以在规划新类时应考虑系列化。须要考虑的标题有:是不是必须跨应用程序域来发送此类?是或不是要远程应用此类?用户将如何使用此类?恐怕他们会从自家的类中派生出2个索要种类化的新类。只要有那种只怕性,就应将类标志为可种类化。除下列处境以外,最棒将所有类都标志为可系列化:
美高梅开户网址 107
美高梅开户网址 108全体的类都永远也不会超过应用程序域。假若有个别类不供给连串化但必要跨越应用程序域,请从 马尔斯halByRefObject 派生此类。
美高梅开户网址 109类存款和储蓄仅适用于其眼下实例的特种指针。例如,假诺有个别类富含非受控的内部存款和储蓄器或文件句柄,请保管将那么些字段标记为 NonSerialized 或根本不连串化此类。
美高梅开户网址 110一些数据成员包括敏感音讯。在那种情状下,建议落实 ISerializable 并仅系列化所供给的字段。 

发表评论

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

网站地图xml地图