ICloneable接口
如果想使自己的自定义类型支持向调用方返回自身同样副本的能力,需要实现标准ICloneable接口。
1 namespace System
2 { 8 public interface ICloneable
9 {
16 object Clone();
17 }
18 }
浅拷贝
System.Object定义了一个名为MemberwiseClone()的成员。这个方法用来获取当前对象的一份浅拷贝。
例:
Point.cs
1 namespace CloneablePoint
2 {
3 // The Point now supports "clone-ability."
4 public class Point : ICloneable
5 {
6 public int X { get; set; }
7 public int Y { get; set; }
8 public PointDescription desc = new PointDescription();
9
10 public Point( int xPos, int yPos, string petName )
11 {
12 X = xPos; Y = yPos;
13 desc.PetName = petName;
14 }
15 public Point( int xPos, int yPos )
16 {
17 X = xPos; Y = yPos;
18 }
19 public Point() { }
20
21 // Override Object.ToString().
22 public override string ToString()
23 {
24 return string.Format("X = {0}; Y = {1}; Name = {2};
ID = {3}
",
25 X, Y, desc.PetName, desc.PointID);
26 }
27
28 // Return a copy of the current object.
29 // Now we need to adjust for the PointDescription member.
30 public object Clone()
31 {
32 // 这个复制每个Ponit字段成员
33 Point newPoint = (Point)this.MemberwiseClone();
34 return newPoint;
35 }
36 }
37 }
PointDescription.cs
1 namespace CloneablePoint
2 {
3 // This class describes a point.
4 public class PointDescription
5 {
6 public string PetName { get; set; }
7 public Guid PointID { get; set; }
8
9 public PointDescription()
10 {
11 PetName = "No-name";
12 PointID = Guid.NewGuid();
13 }
14 }
15 }
Program.cs
1 namespace CloneablePoint
2 {
3 class Program
4 {
5 static void Main( string[] args )
6 {
7 Console.WriteLine("***** Fun with Object Cloning *****
");
8 Console.WriteLine("Cloned p3 and stored new Point in p4");
9 Point p3 = new Point(100, 100, "Jane");
10 Point p4 = (Point)p3.Clone();
11
12 Console.WriteLine("Before modification:");
13 Console.WriteLine("p3: {0}", p3);
14 Console.WriteLine("p4: {0}", p4);
15 p4.desc.PetName = "My new Point";
16 p4.X = 9;
17
18 Console.WriteLine("
Changed p4.desc.petName and p4.X");
19 Console.WriteLine("After modification:");
20 Console.WriteLine("p3: {0}", p3);
21 Console.WriteLine("p4: {0}", p4);
22 Console.ReadLine();
23 }
24 }
25 }
请注意,如果Ponint包含任何引用类型成员变量,MemberwiseClone()将这些引用复制到对象中(即浅复制)。如果想要支持真正的深复制,需要在克隆过程中创建任何引用类型变量的新实力。
深拷贝
Point.cs
namespace CloneablePoint { public class Point : ICloneable { public int X { get; set; } public int Y { get; set; } public PointDescription desc = new PointDescription(); public Point( int xPos, int yPos, string petName ) { X = xPos; Y = yPos; desc.PetName = petName; } public Point( int xPos, int yPos ) { X = xPos; Y = yPos; } public Point() { } public override string ToString() { return string.Format("X = {0}; Y = {1}; Name = {2}; ID = {3} ", X, Y, desc.PetName, desc.PointID); } public object Clone() { Point newPoint = (Point)this.MemberwiseClone(); PointDescription currentDesc = new PointDescription(); currentDesc.PetName = this.desc.PetName; newPoint.desc = currentDesc; return newPoint; } } }
PointDescription.cs
namespace CloneablePoint { public class PointDescription { public string PetName { get; set; } public Guid PointID { get; set; } public PointDescription() { PetName = "No-name"; PointID = Guid.NewGuid(); } } }
Program.cs
namespace CloneablePoint { class Program { static void Main( string[] args ) { Console.WriteLine("***** Fun with Object Cloning ***** "); Console.WriteLine("Cloned p3 and stored new Point in p4"); Point p3 = new Point(100, 100, "Jane"); Point p4 = (Point)p3.Clone(); Console.WriteLine("Before modification:"); Console.WriteLine("p3: {0}", p3); Console.WriteLine("p4: {0}", p4); p4.desc.PetName = "My new Point"; p4.X = 9; Console.WriteLine(" Changed p4.desc.petName and p4.X"); Console.WriteLine("After modification:"); Console.WriteLine("p3: {0}", p3); Console.WriteLine("p4: {0}", p4); Console.ReadLine(); } } }