原型模式就是依照样本复制一个出来。就像复印机原理一样的。当你需要一个同样的对象时。你并不需要重新构建这个类。你直接使用CLONE就可以得到这个类。
在实际编程中,由于在某些情况下构建一个对象很难,这个时候你就要用到原型模式了,直接复制。
复制分为两种
1、深度复制
深度复制就是,值类型和引用类型都同时指向不同的内存地址
2、浅复制
浅复制就是,值类型是新内存地址,而引用类型是同一个内存地址,因此你修改了值类型正本和副本相互不影响,你修改了引用类型正本和副本相互影响。
两种复制方法在实际当中的使用:
public class IdInfo { public int IdNumber; public IdInfo(int IdNumber) { this.IdNumber = IdNumber; } } public class Person { public int Age; public string Name; public IdInfo IdInfo; /// <summary> /// 浅复制 /// </summary> /// <returns></returns> public Person ShallowCopy() { return (Person)this.MemberwiseClone(); } /// <summary> /// 深复制 /// </summary> /// <returns></returns> public Person DeepCopy() { Person other = (Person)this.MemberwiseClone(); other.IdInfo = new IdInfo(IdInfo.IdNumber); other.Name = String.Copy(Name); return other; } }
结果测试:
static void Main(string[] args) { // Create an instance of Person and assign values to its fields. Person p1 = new Person(); p1.Age = 42; p1.Name = "山姆"; p1.IdInfo = new IdInfo(6565); // Perform a shallow copy of p1 and assign it to p2. Person p2 = p1.ShallowCopy(); // Display values of p1, p2 Console.WriteLine("Original values of p1 and p2:"); Console.WriteLine(" p1 instance values: "); DisplayValues(p1); Console.WriteLine(" p2 instance values:"); DisplayValues(p2); // Change the value of p1 properties and display the values of p1 and p2. p1.Age = 32; p2.Age = 42; p1.Name = "山姆"; p2.Name = "王小小"; p2.IdInfo.IdNumber = 7878; p1.IdInfo.IdNumber = 9898; Console.WriteLine("\nValues of p1 and p2 after changes to p1:"); Console.WriteLine(" p1 instance values: "); DisplayValues(p1); Console.WriteLine(" p2 instance values:"); DisplayValues(p2); // Make a deep copy of p1 and assign it to p3. Person p3 = p1.DeepCopy(); // Change the members of the p1 class to new values to show the deep copy. p1.Name = "乔治"; p1.Age = 39; p1.IdInfo.IdNumber = 8641; Console.WriteLine("\nValues of p1 and p3 after changes to p1:"); Console.WriteLine(" p1 instance values: "); DisplayValues(p1); Console.WriteLine(" p3 instance values:"); DisplayValues(p3); Console.Read(); } public static void DisplayValues(Person p) { Console.WriteLine(" Name: {0:s}, Age: {1:d}", p.Name, p.Age); Console.WriteLine(" Value: {0:d}", p.IdInfo.IdNumber); }
运行结果:
描述:
.NET Freamwork 内置的每个继承自System.Object都有保护成员方法:
[SecuritySafeCritical]
protected object MemberwiseClone();
.NET给我提供了一个System.ICloneable的接口,我们通过实现这个接口,可以为对象提供自定义的克隆方法。
/// <summary> /// 杯子类 /// </summary> public class Cup : ICloneable { /// <summary> /// 生产厂家 /// </summary> public Factory Factory { get {return _factory;} set {_factory = value;} } #region ICloneable 成员 public object Clone() { return this.MemberwiseClone(); } #endregion } static void Main(string[] args) { Cup cup = new Cup(); cup.Height = 2; Cup cup1 = (Cup)cup.Clone(); cup1.Height = 1; Console.WriteLine(cup.Height == cup1.Height); }
通过序列化的形式来进行对象的复制
/// <summary> /// 序列化和反序列化辅助类 /// </summary> public class SerializableHelper { public string Serializable(object target) { using (MemoryStream stream = new MemoryStream()) { new BinaryFormatter().Serialize(stream, target); return Convert.ToBase64String(stream.ToArray()); } } public object Derializable(string target) { byte[] targetArray = Convert.FromBase64String(target); using (MemoryStream stream = new MemoryStream(targetArray)) { return new BinaryFormatter().Deserialize(stream); } } public T Derializable<T>(string target) { return (T)Derializable(target); } } ///在类中实例CLONE接口 #region IColorDemo 成员 public IColorDemo Clone() { string target= SerializableHelper.Serializable(this); return SerializableHelper.Derializable<IColorDemo>(target); } #endregion
通过二进制序列化来进行复制,都是深复制。
参考文档:
http://www.cnblogs.com/siqing99/archive/2012/04/03/2430918.html
http://www.cnblogs.com/hegezhou_hot/archive/2010/12/04/1896471.html
https://msdn.microsoft.com/zh-cn/library/system.object.memberwiseclone.aspx
原文:http://www.cnblogs.com/lystory/p/5067253.html