构建可克隆的对象(ICloneable)

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};\nID = {3}\n",
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 *****\n");
 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("\nChanged 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};\nID = {3}\n",
            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 *****\n");
            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("\nChanged p4.desc.petName and p4.X");
            Console.WriteLine("After modification:");
            Console.WriteLine("p3: {0}", p3);
            Console.WriteLine("p4: {0}", p4);
            Console.ReadLine();
        }
    }
}

posted @ 2017-01-09 15:46  KUYUTI  阅读(272)  评论(0编辑  收藏  举报