VB.NET 中对象的克隆
侯永锋
在 3DMAX 里面,做好一个物体(父物体)以后,可以选择 Edit 菜单中的 Clone ,下面有三中选项: Copy (生成一个同模样的子物体,两者的操作互不影响), Instance (父子互动,父物体的操作同样影响子物体,子物体也一样),还有一个 Reference (暂不考虑)。
在 VB.NET ,同样会碰到这样的问题。创建一个复杂对象(可能有很多种不同的数据类型)的实例,进行了一系列操作之后,想让一个中间变量或几个(另外的实例)保存它的状态,我们一般采取逐个变量赋值,有时候会写很长的代码:)这实际上就是上述的 Copy 问题。而对于 Instance ,很简单 , 新建一个实例,指向一下就可以了:
Dim objA As New CResume ‘Cresume 是一个自定义的记录简历信息的类
然后进行初始化,比如:
objA.Name=”AAA”
objA.Address=”Shanghai , China”
……
Dim objB As New CResume ‘ 新建一个实例
objB = objA
这样的话, objB 跟 objA 有相同状态,值得注意的是 objB 改变一个 Name ,比如:
objB.Name=”BBB”
而实际上, objA 的 Name 也变为“ BBB ”,理由很简单。它们指向同一块内存空间。
下面我们重点讨论对象的 Clone 问题,即 Copy 以后的各个对象互不影响,关键是如何采用简单的方法解决我们的问题, ** MemoryStream ** 和 ** BinFormatter ** 配合一下可以很简单的把对象克隆。
** MemoryStream ** ** , ** 我以前提到过,是支持存储区为内存的流。
** BinFormatter ** ** , ** 主要以二进制形式序列化和反序列化对象。
主要思路:
先用 ** BinFormatter ** 的 ** Serialize ** 方法,把对象存储在 ** MemoryStream ** 流中,(操作跟其他 ** Stream ** 一样),然后 ** Deserialize ** 反序列化,得到一个流式的数据,转化为原来对象的类型就可以了。是不是很简单?呵呵。看一下代码再说:
CResume 类的代码:
Imports System.IO
Imports System.Runtime.Serialization.Formatters
1<serializable()> Public Class CResume
2
3‘注意类前面加上 Serializable() 属性,否则不可以序列化
4
5Dim m_Name As String ' 姓名
6
7Dim m_Address As String ' 地址
8
9Public Property Address() As String
10
11Get
12
13Return m_Address
14
15End Get
16
17Set(ByVal NewAddress As String)
18
19m_Address = NewAddress
20
21End Set
22
23End Property
24
25Public Property Name() As String
26
27Get
28
29Return m_Name
30
31End Get
32
33Set(ByVal NewName As String)
34
35m_Name = NewName
36
37End Set
38
39End Property
40
41Public Function Clone() As CResume
42
43Dim BF As New Binary.BinaryFormatter()
44
45Dim MS As New MemoryStream()
46
47BF.Serialize(MS, Me)
48
49MS.Position = 0
50
51Return (CType(BF.Deserialize(MS), CResume))
52
53End Function
54
55End Class
56
57在 Form 里面可以这样调用
58
59Dim Resume1 As New CResume()
60
61Dim Resume2 As New CResume()
62
63Resume1.Name = "AAA"
64
65Resume1.Address = " Shanghai , China "
66
67Resume2 = Resume1.Clone()
68
69Resume1.Name = "BBB"
70
71Resume1.Address = " Beijing , China "
72
73Debug.WriteLine(Resume1.Name) ‘依然是 AAA
74
75Debug.WriteLine(Resume1.Address)
76
77总结:主要调用了 VB.NET 的流和序列化技术,使得对象的克隆免去了繁琐的读写操作,也简化了代码。</serializable()>