浏览器大全:是一个提供流行浏览器教程、在线学习分享的学习平台!

C#与.NET中的原型克隆[zt]

发表日期: 17/04/2002 18:51:10
发表人: Ashish Jaiman
发表人信箱: Ashish.Jaiman@lexign.com
发表人网址: http://www.lexign.com

与其不断地创建类实例,有时反不如使用原型克隆方法,拷贝已有的实例,然后适当地作些改动。当使用的子类仅仅在对象类型上不同于父类,也可以用原型克隆方法来减少子类数量。

===========================================================
创建类的实例是相当花费时间而且比较复杂的事,与其不断地创建类实例,有时反不如使用原型克隆方法,拷贝已有的实例,然后适当地作些改动。当使用的子类仅仅在对象类型上不同于父类,也可以用原型克隆方法来减少子类数量。
原型设计模式的重点在于“用克隆的方式创建对象”。有时为了得到不同的对象类型而创建不同子类,这时用原型设计就只需要创建一个子类(在这个子类里有指向基类的引用),然后创建这个子类的对象。以后就只要创建这个子类的对象就能用了。每个对象都是能被克隆的,使用原型克隆将大大减少子类的数量。

用系统的ICloneable命名可以实现克隆。ICloneable的唯一成员就是Clone方法,它将返回一个新的类实例,并包含与科隆对象同样的参数值。

ICloneable.Clone 方法的描述:
[Visual Basic] Function Clone() As Object
[C#] object Clone();

必需指出的是,Clone()方法是一种“浅”拷贝,它只返回指向原型的引用。另外还有一种“深”拷贝,它拷贝整个实例对象。用ISerializable接口可以实现对象的深拷贝。

克隆对象的任何变化都将影响到原型,反之亦然。克隆方法的另外一个不足之处在于它的子类都必需使用Clone()方法,很难使用其他的拷贝方法。

在示范例子里(文末可以下载),我创建了一个EmpData类,它有ICloneable和ISerializable二种接口。ICloneable用于创建“浅”拷贝,ISerializable用于创建“深”拷贝。前者仅拷贝对象的引用,后者则拷贝整个对象。EmpData类有二个方法:GetEmpData和ChangeEmpData。前者将源对象克隆成为一个字符串,后者则可以对其进行修改。

二种方法都可以被使用,并用于验证深浅克隆方法的不同。浅克隆对象的变化将影响到被克隆的原型对象,而深克隆对象的变化则不改变原型对象数据。

EmpData的构造函数是挺花时间的,因为它要读取XML文件并创建对象。

XML文件:
<employees>
<employee>
<firstname>ashish</firstname>
<lastname>jaiman</lastname>
</employee>
<employee>
<firstname>jaya</firstname>
<lastname>pandey</lastname>
</employee>
<employee>
<firstname>neeraj</firstname>
<lastname>jaiman</lastname>
</employee>
<employee>
<firstname>ashutosh</firstname>
<lastname>sharma</lastname>
</employee>
<employee>
<firstname>zerman</firstname>
<lastname>billingslea</lastname>
</employee>
<employee>
<firstname>bernd</firstname>
<lastname>burkhardt</lastname>
</employee>
<employee>
<firstname>sanjeev</firstname>
<lastname>bhutt</lastname>
</employee>
<employee>
<firstname>li</firstname>
<lastname>li</lastname>
</employee>
</employees>

C#执行程序:
using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 [Serializable()]
 public class CEmpData: ICloneable,ISerializable {
 private ArrayList ArrEmp;
 public CEmpData(){
  ArrEmp = new ArrayList();
  InitializeData();
  }
 private void InitializeData(){
  XmlDocument xmlDoc = new XmlDocument();
  CEmp objEmp;
  xmlDoc.Load("empdata.xml");
  foreach(XmlNode node in xmlDoc.DocumentElement.ChildNodes){
   objEmp = new CEmp();
   objEmp.FName = node.SelectSingleNode("firstname").InnerText;
   objEmp.LName = node.SelectSingleNode("lastname").InnerText; 
   ArrEmp.Add (objEmp); 
   }
  }
 public CEmpData(SerializationInfo info,StreamingContext context){
  int intCount=0;
  CEmp objEmp;
  ArrEmp = new ArrayList();
  intCount = (int)info.GetValue("emp_count", intCount.GetType());
  for (int intIndex = 0;intIndex<intCount;intIndex++){
   objEmp = new CEmp(info,context,intIndex);
   ArrEmp.Add(objEmp);
   }
  }
 public void GetObjectData(SerializationInfo info,StreamingContext context){
  CEmp objEmp;
  info.AddValue("emp_count", ArrEmp.Count);
  for (int intIndex = 0;intIndex<ArrEmp.Count ;intIndex++) {
   objEmp = (CEmp)ArrEmp[intIndex];
   objEmp.GetObjectData(info,context,intIndex); 
   }
  }
 public object Clone(){
  return this;
  }
 public object Clone(bool Deep){
  if(Deep) 
   return CreateDeepCopy();
  else
   return Clone();
  }
 private CEmpData CreateDeepCopy(){
  CEmpData objEmpCopy;
  Stream objStream;
  BinaryFormatter objBinFormatter = new BinaryFormatter();
  try{
   objStream = File.Open("Empdata.bin", FileMode.Create);
   objBinFormatter.Serialize(objStream, this);
   objStream.Close();
   objStream = File.Open("Empdata.bin", FileMode.Open);
   objEmpCopy = (CEmpData)objBinFormatter.Deserialize(objStream);
   objStream.Close();
   return objEmpCopy;
   }
  catch(Exception ex){
   Console.WriteLine (ex.ToString());
   return null;
   }
  }
 public string GetEmpData(){
  string strEmpData="";
  for (int intCount = 0;intCount < ArrEmp.Count;intCount++){
   strEmpData = strEmpData + ((CEmp)ArrEmp[intCount]).FName + "\t" + ((CEmp)ArrEmp[intCount]).LName+ "\n";
   }
  return strEmpData;
  }
 public void ChangeEmpData(){
  foreach (CEmp objEmp in ArrEmp){
   objEmp.FName ="FirstName";
   objEmp.LName ="LastName";
   }
  }
 }
using System;
using System.Runtime.Serialization;
public class CEmp {
 private string mstrFName;
 private string mstrLName;
 public string FName{
  get{return mstrFName;}
  set{mstrFName = value;}
 }
 public string LName{
  get{return mstrLName;}
  set{mstrLName = value;}
  }
 public CEmp(){}
 public CEmp(SerializationInfo info, StreamingContext context, int intIndex){
  string temp = "temp";
  mstrFName = (string)info.GetValue("emp_fname" + intIndex,temp.GetType());
  mstrLName = (string)info.GetValue("emp_lname" + intIndex, temp.GetType());
  }
 public void GetObjectData(SerializationInfo info, StreamingContext context, int intIndex){
  info.AddValue("emp_fname" + intIndex, mstrFName);
  info.AddValue("emp_lname" + intIndex, mstrLName);
  }
 }


VB.NET 执行程序:
Imports System.Xml
Imports System.IO
Imports System.Collections
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

<Serializable()> Public Class CEmpData
Implements ICloneable, ISerializable
Private ArrEmp As ArrayList

Public Sub New()
Dim xmldoc As New XmlDocument()
Dim node As XmlNode
Dim objEmp As CEmp
ArrEmp = New ArrayList()
xmldoc.Load("empdata.xml")
For Each node In xmldoc.DocumentElement.ChildNodes
objEmp = New CEmp()
objEmp.FName = node.SelectSingleNode("firstname").InnerText
objEmp.LName = node.SelectSingleNode("lastname").InnerText
ArrEmp.Add(objEmp)
Next
End Sub

Public Sub New(ByVal info As SerializationInfo, _
ByVal context As StreamingContext)
Dim intIndex As Integer
Dim intCount As Integer
Dim objEmp As CEmp
ArrEmp = New ArrayList()
intCount = CInt(info.GetValue("emp_count", GetType(String)))
For intIndex = 0 To intCount - 1
objEmp = New CEmp(info, context, intIndex)
ArrEmp.Add(objEmp)
Next
End Sub

Public Function Clone() As Object Implements ICloneable.Clone
Try
Return Me
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Function

Public Function Clone(ByVal Deep As Boolean) As Object
Try
If Deep Then
Return CreateDeepCopy()
Else
Return Clone()
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Function

Private Function CreateDeepCopy() As CEmpData
Dim objEmpCopy As CEmpData
Dim objStream As Stream
Dim objBinFormatter As New BinaryFormatter()
Try
objStream = File.Open("Empdata.bin", FileMode.Create)
objBinFormatter.Serialize(objStream, Me)
objStream.Close()
objStream = File.Open("Empdata.bin", FileMode.Open)
objEmpCopy = CType(objBinFormatter.Deserialize(objStream), _
CEmpData)
objStream.Close()
CreateDeepCopy = objEmpCopy
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Function

Public Sub GetObjectData( _
ByVal info As System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext) _
Implements System.Runtime.Serialization.ISerializable.GetObjectData
Dim intIndex As Integer
Dim objEmp As CEmp
info.AddValue("emp_count", ArrEmp.Count)
For intIndex = 0 To ArrEmp.Count - 1
objEmp = ArrEmp(intIndex)
objEmp.GetObjectData(info, context, intIndex)
Next
End Sub

Public Function GetEmpData() As String
Dim intCount As Integer
Dim strEmpData As String
For intCount = 0 To ArrEmp.Count - 1
strEmpData = strEmpData & CType(ArrEmp(intCount), _
CEmp).FName & Chr(9) & CType(ArrEmp(intCount), _
CEmp).LName & Chr(13)
Next
GetEmpData = strEmpData
End Function

Public Sub ChangeEmpData()
Dim objEmp As CEmp
For Each objEmp In ArrEmp
objEmp.FName = "FirstName"
objEmp.LName = "LastName"
Next
End Sub
End Class

引入System.Runtime.Serialization:
Public Class CEmp
Private mstrFName As String
Private mstrLName As String

Public Property FName() As String
Get
FName = mstrFName
End Get
Set(ByVal Value As String)
mstrFName = Value
End Set
End Property

Public Property LName() As String
Get
LName = mstrLName
End Get
Set(ByVal Value As String)
mstrLName = Value
End Set
End Property

Public Sub New()

End Sub

Public Sub New(ByVal info As SerializationInfo, _
ByVal context As StreamingContext, ByVal intIndex As Integer)
mstrFName = CStr(info.GetValue("emp_fname" & intIndex, _
GetType(String)))
mstrLName = CStr(info.GetValue("emp_lname" & intIndex, _
GetType(String)))
End Sub

Public Sub GetObjectData(ByVal info As SerializationInfo, _
ByVal context As StreamingContext, ByVal intIndex As Long)
info.AddValue("emp_fname" & intIndex, mstrFName)
info.AddValue("emp_lname" & intIndex, mstrLName)
End Sub

End Class

本文附件:http://www.chinaOk.net/down/prototype.zip

相关软件

2345加速浏览器官方版

2345加速浏览器官方版 | 56.2MB

2345加速浏览器官方版

新一代2345加速浏览器采用Chromium和IE双内核,主打极速与安全特性。基于Chromium深度定制,引入网页智能预加载技术,访问网页更快速..

QQ浏览器官方正式版

QQ浏览器官方正式版 | 49.67MB

QQ浏览器官方正式版

QQ浏览器秉承TT浏览器1-4系列方便易用的特点,但技术架构不同,交互和视觉表现也重新设计,采用Chromium内核+IE双内核,让浏览快速稳定...

百度浏览器最新版下载

百度浏览器最新版下载 | 13.3MB

百度浏览器最新版下载

q百度浏览器,是一款简洁轻快、智能懂你的浏览器。依靠百度强大的搜索平台,在满足用户浏览网页的基础上,它整合百度体系业务优势,带给用户更方便的浏览方式功能...

UC浏览器官方正式版

UC浏览器官方正式版 | 44.2MB

UC浏览器官方正式版

UC浏览器(UC Browser)是UC Mobile Limited在2004年8月开发的一款软件,分uc手机浏览器和uc浏览器电脑版。UC浏览器是全球使用量最大的第三方手机浏览器...

猎豹浏览器2022最新版下载

猎豹浏览器2022下载 | 45MB

猎豹浏览器2022最新版下载

猎豹安全浏览器对Chrome的Webkit内核进行了超过100项的技术优化,访问网页速度更快。其具有首创的智能切换引擎,动态选择内核匹配不同网页...

360安全浏览器官方版下载

360安全浏览器下载 | 21.4MB

360安全浏览器官方版下载

360安全浏览器拥有全国最大的恶意网址库,采用恶意网址拦截技术,可自动拦截挂马、欺诈、网银仿冒等恶意网址。独创沙箱技术,在隔离模式即使访问****也不会感染...