Kevin Shan

博客园 首页 新随笔 联系 订阅 管理
  11 Posts :: 0 Stories :: 104 Comments :: 1 Trackbacks

.NET Framework提供了将对象序列化和反序列化的能力。利用这种机制,我们可以将对象实例的状态存储到存储媒体上,也可以将对象从一个地方传递到另一个地方。

.NET Framework提供了一些用于序列化的类。一个是BinnaryFormatter,它使用二进制格式序列化对象。另一个是SoapFormatter,它使用soap格式(基于XML格式)序列化对象。还可以使用XMLSerializer将对象序列化成XML格式。然而这种序列化机制是有一定限制的,它只能序列化特定的对象。这些对象要么是从MarshalByRefObject派生的对象,要么是标记为Serializable的简单类型对象。像System.Windows.Forms.Control这类复杂的对象就不能被支持。

今天我要介绍的是如何序列化System.Windows.Forms.Control这类复杂的对象。在介绍之前,我们先看看序列化和反序列化的流程。

序列化反序列化流程图

 

分离出复杂的逻辑,最简单的逻辑只有两步,第一步-序列化过程:将内存中的对象数据用XML格式的数据表示。第二步-反序列化过程:构造一个新对象,并将XML格式表示的数据赋值给这个新的对象。这样,原始对象和新构造的对象会有同样的数据,即表示同一种状态。

经常使用VS2005,VS2008等IDE的开发人员,特别是做过Design Time开发的开发人员可能会注意到,这个过程其实和IDE自动生成控件代码的过程相似。

IDE设计编译流程

在使用IDE的过程中,我们在Design环境中给Form拖一个TextBox控件,IDE会在Design环境中创建一个TextBox控件,并生成相关C#或者VB等格式的代码。这个阶段叫设计时(DesignTime)。这个过程类似我们刚才讲到的第一步-序列化过程。而我们点击运行的时候,这些文本格式的代码又会被编译运行,根据编译的代码生成一个新TextBox控件在Form上显示。这个阶段叫运行时(RunTime)。这个过程就类似我们刚才讲到的第二步-反序列化过程。可以看出来,IDE在DesignTime下是将控件实例序化成C#或VB等代码。而在RunTime下是将代码编译运行,生成新的控件实例来保持DesignTime下设计的状态与RunTime下显示的状态一致。事实上,这也是序列化和反序列化的一种方式。

既然IDE的这个过程也是序列化和反序列化的方式,那么IDE是怎么实现复杂控件序列化和反序列化的呢?这可能需要另外一篇文章才能讲清楚,这里暂不研究。不过我们可以知道,IDE是有能力做这件事情的。我们也可以利用IDE的这种能力,来实现复杂控件的序列化和反序列化。

下面这段代码演示了如何利用IDE的这种能力序列化一个Object。

SaveObject

下面这段代码演示了如何利用IDE的这种能力反序列化一个Object。 

LoadObject

利用IDE的这种能力,我们还可以做很多事情,比如深度克隆控件。有时候,我们需要克隆一个复杂的控件,然而办法有限,要么使用反射枚举控件所有字段赋值,要么给所有属性一个一个赋值。而属性之间的依赖关系,引用类型的属性如何处理等都是难题。利用控件序列化和反序列化,可以轻松实现控件的克隆。再比如在RunTime下得到控件的C#,VB等代码,因为序列化的中间产物就是C#,VB等代码,所以利用这个机制很容易实现。这些代码我写了一个类库,需要的可以和我联系。代码太多,在这里就不贴了。

补充:现在我已经把源代码上传了。可以在这里下载

原创文章,转载请注明出处。KevinShan Email:txhak@163.com。

posted on 2008-05-27 17:03 Kevin Shan 阅读(1673) 评论(48)  编辑 收藏 所属分类: .NET相关技术

Feedback

#1楼  2008-05-27 18:13 jisen      
沙发!
麻烦博主给发一份
jisen008@hotmail.com,谢谢。
  回复  引用  查看    

#2楼  2008-05-27 18:16 ted      
不错,
请问在Runtime可以那到Design Time下的各种Serveice来进行控件复制吗,应该如何做哪?
  回复  引用  查看    

#3楼  2008-05-27 18:24 jeff377      
收藏
  回复  引用  查看    

#4楼 [楼主] 2008-05-27 18:37 Kevin Shan      
@jisen
已经发送给你了。
  回复  引用  查看    

#5楼 [楼主] 2008-05-27 18:39 Kevin Shan      
@ted
在RunTime下可以得到各种Service,这时需要在RunTime下新建一个DesignSurface。具体方法文章代码中可以看出。
  回复  引用  查看    

#6楼  2008-05-27 19:37 evo [未注册用户]
evolution124@gmail.com

我也需要一份 谢谢博主
  回复  引用    

#7楼  2008-05-27 19:59 HOH      
方便的话,楼主也发我一份。谢谢。
hoh728@163.com
  回复  引用  查看    

好文!博主,发一份研究下.
  回复  引用    

#9楼  2008-05-27 20:39 jerry qian [未注册用户]
楼主请给我一个
jciwolf@hotmail.com
  回复  引用    

#10楼 [楼主] 2008-05-27 20:45 Kevin Shan      
@evo
@HOH
@肥田小鱼
@jerry qian
已经发给你们了。
  回复  引用  查看    

#11楼  2008-05-27 20:46 墙头草      
neptune880312@hotmail.com 希望楼主也发我一份,谢谢楼主!
  回复  引用  查看    

#12楼  2008-05-27 20:49 队长      
我也想看看源码学习学习,zhaojj@gmail.com
谢谢!
  回复  引用  查看    

#13楼  2008-05-27 20:49 steven hu [未注册用户]
huxj1985@gmail.com

我也要一份 谢谢
  回复  引用    

#14楼  2008-05-27 20:57 簡簡單單..      
谢谢分享! Shinaterry@126.com
  回复  引用  查看    

#15楼  2008-05-27 21:03 蜀山雪狼      
楼主是否可以给我一份,谢谢。
ldaqiang#gmail.com
  回复  引用  查看    

#16楼 [楼主] 2008-05-27 21:11 Kevin Shan      
@墙头草
@队长
@steven hu
@簡簡單單..
@蜀山雪狼
已经发给你们了。
  回复  引用  查看    

gqy2000@163.com 希望楼主也发我一份,谢谢楼主!
  回复  引用    

#18楼  2008-05-27 21:20 一味      
请发给我一份,谢谢
  回复  引用  查看    

#19楼 [楼主] 2008-05-27 22:50 Kevin Shan      
@白云城主
@一味
已经发过你们了。
  回复  引用  查看    

#20楼  2008-05-27 23:16 aaaaaaaaa [未注册用户]
很不错!
  回复  引用    

代码中designSurface.BeginLoad(new DefaultCodeDomDesignerLoader())里的DefaultCodeDomDesignerLoader是什么?是你的一个自定义类吧?请给出来好吗?或者请发一份类库代码好吗?谢谢了。
icesee@126.com
  回复  引用    

#22楼  2008-05-28 07:45 solunar66      
虽然没有应用场景,但是还是挺感兴趣的,希望博主有空给我发一份,谢谢。
solunar66@126.com
  回复  引用  查看    

#23楼  2008-05-28 08:26 點多 [未注册用户]
hackerace@163.com 谢谢楼主!
  回复  引用    

#24楼  2008-05-28 08:33 zdq2601 [未注册用户]
谢谢
给我发一份
zdq2601@gmail.com

  回复  引用    

#25楼  2008-05-28 08:44 颜斌      
yanbinboy@163.com
谢谢
  回复  引用  查看    

#26楼  2008-05-28 09:34 macou1005 [未注册用户]
谢谢
给我一份
macou1005@126.com
  回复  引用    

#27楼  2008-05-28 09:40 ^ō^ [未注册用户]
性能如何?
  回复  引用    

#28楼  2008-05-28 10:28 kouding [未注册用户]
谢谢 参考一下

guestnhk@hotmail.com
  回复  引用    

#29楼  2008-05-28 10:55 allies [未注册用户]
gbaonly@163.com 给份研究研究!
  回复  引用    

#30楼 [楼主] 2008-05-28 10:58 Kevin Shan      
@斯克迪亚
@solunar66
@點多
@zdq2601
@颜斌
@macou1005
@kouding
@allies
已发给你们了。

@斯克迪亚
DefaultCodeDomDesignerLoader是我自己实现的类。

@^ō^
由于克隆控件等都是有限次的操作,在实际使用中并没有发现性能方面的问题。不过如果有性能瓶颈,可以将多次操作放在同一个DesignSurface就能得到很大的改善。

  回复  引用  查看    

#31楼  2008-05-28 11:06 allies [未注册用户]
博主效率真快~~ 3Q!
  回复  引用    

#32楼  2008-05-28 12:16 kegogo      
谢谢 参考一下
liuke209@yahoo.com.cn
  回复  引用  查看    

#33楼  2008-05-28 12:37 AQiang [未注册用户]
关注!感谢分享.给我发一份:dongfang106@163.com
  回复  引用    

#34楼  2008-05-28 13:38 jean [未注册用户]
楼主给我一份吧,谢谢!
huangjun4444@163.com
  回复  引用    

#35楼  2008-05-28 14:03 菩提d [未注册用户]
博主也给我来一份吧,万分感谢!
  回复  引用    

#36楼  2008-05-28 14:42 小二郎 [未注册用户]
希望也能给我来一份,谢谢博主


yeke_1998@163.com
  回复  引用    

楼主发一份给在下学习下吧 万分感谢
hwqismyname@163.com
  回复  引用    

#38楼  2008-05-28 17:06 Silverfox [未注册用户]
对楼主的研究很感兴趣,有空发来一份看看,感谢!
  回复  引用    

#39楼 [楼主] 2008-05-28 18:30 Kevin Shan      
@kegogo
@AQiang
@jean
@菩提d
@小二郎
@.NET修行者
@Silverfox
已经给你们发了一份。
  回复  引用  查看    

#40楼  2008-05-28 19:05 byrybye [未注册用户]
byrybye@163.com
谢谢
  回复  引用    

#41楼  2008-05-28 19:28 byrybye [未注册用户]
麻烦那位兄弟 发一份。谢谢
  回复  引用    

#42楼  2008-05-29 15:11 无忧浪子      
10000_119@163.com 谢谢博主
  回复  引用  查看    

#43楼  2008-05-29 17:15 tony.zjb      
zjbtony@126.com
博主也发给我一份吧 谢谢
  回复  引用  查看    

楼主,发一份给我学习学习吧,非常感谢!
gesheng_hd@sina.com
  回复  引用    

#45楼  2008-06-12 10:42 潜水的青蛙      
搜序列化控件时一不小心到这了。复制了代码正在测试,发现有一个new DefaultCodeDomDesignerLoader()不能用。
博主,把代码也给俺一份吧~
dczsf@163.com
  回复  引用  查看    

#46楼  2008-06-20 13:57 独角兽 [未注册用户]
传我一份。。。
elivehai@163.com
  回复  引用    

#47楼 [楼主] 2008-06-23 15:45 Kevin Shan      
@byrybye
@无忧浪子
@tony.zjb
@gesheng_hd
@潜水的青蛙
@独角兽
已经把源文件上传了,可以在这里下载

  回复  引用  查看    

#48楼  2008-08-18 19:05 逗号 [未注册用户]
非常佩服楼主的实力,本人太菜,看不太懂!可否多加些注释.或举个例子发到我邮箱里,让我再挑战一下,本人十分感谢!
  回复  引用    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-23 15:43 编辑过