序列化part2

来源:互联网 发布:大连知润信息 编辑:程序博客网 时间:2024/06/05 15:34

在序列化part1中,我曾经提到序列化的目的有2个:

1.   以某种存储形式使自定义对象持久化;

2.  将对象从一个地方传递到另一个地方;

目的1已经在part1中详细讲解了,下面重点讲解目的2。

什么叫“将对象从一个地方传递到另一个地方”,这里的地方指不同的应用程序域、不同的进程、非同一机器等。

下面先让大家看两个例子,请注意这两个例子的结果有什么不同。

代码的IDE环境:vs2008

1、新建一个namespace为ClassLib的DemoClass类,程序集为ClassLib

 

将上面的Library编译成ClassLib.dll.

2、重新建立一个namespace为DiffrentDomainUse的Program应用程序类

注意:需要引用上面的ClassLib.dll.

代码如下:

   

结果:

 

3、如果将Program应用程序类改为如下呢?

我们在新的程序域中创建实例,赋值给obj1、obj2.咋一听,应该没什么问题啊,但是运行后出现

“程序集“ClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的类型“ClassLib.DemoClass”未标记为可序列化。”错。

这是为什么呢?不是一样类型的变量吗?

这个问题问的好。简单的说应用程序域 (application domain) (AppDomain) 是一种边界,它由公共语言运行库围绕同一应用程序范围内创建的对象建立(即,从应用程序入口点开始,沿着对象激活的序列的任何位置)。应用程序域有助于将在一个应用程序中创建的对象与在其他应用程序中创建的对象隔离,以使运行时行为可以预知。在一个单独的进程中可以存在多个应用程序域。

大家看到隔离二字没?,也就是代码3中由在新的程序域中创建了一个变量,而其变量类型申明却在当前默认的程序域中,这是不允许的了,因为当前的程序域不能什么也不做就能引用其他域的对象啊。所以会报错(不同进程、不同机器也是这个道理)。

那么怎么才能跨程序域调用呢?

大家看到代码1吗,就是DemoClass类,在类上面添加属性 [Serializable]。当我们将对象标记为可序列化时,然后进行上面的操作时,对象本身已经由另一应用程序域(远程)传递到了本地应用程序域中。因为其要求将对象标记为可序列化,所以不难想到,具体的方法是 先在远程创建对象,接着将对象序列化,然后传递对象,在本地进行反序列化,最后还原对象(详细见我的Remoting之追根求源一)。

DemoClass类,在类上面添加属性 [Serializable]后编译,由DiffrentDomainUse引用,运行结结果:

怎么样,跟上面一样的。

说穿了这就有些像传值,方法调用时的传值就是产生个拷贝,所以你看上面的结果中应用程序域为:DiffrentDomainUse.exe.

当然了,若将Demo类改为public class DemoClass:MarshalByRefObject。那结果又是另外一回事了(具体见Remoting之追根求源一)。

好了,上面就是关于序列化用途2的一些讲解,希望大家能理解。