网摘 |  收藏 | 

构建可克隆对象(ICloneable)

《C# 与.NET 4 高级程序设计》笔记

一个引用变量分配给另一个引用变量,那么两个引用将指向内存中的同一个对象。通过任何一个引用都能修改堆上的同样对象。

 // A class named Point.
    public class Point //: ICloneable
    {
        public int X { get; set; }
        public int Y { get; set; }
     
        public Point(int xPos, int yPos)
        {
            X = xPos; 
            Y = yPos;
        }
        public Point() { }

        // Override Object.ToString().
        public override string ToString()
        {
            return string.Format("X = {0}; Y = {1};", X, Y);
        }
    }

 

        static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with Object Cloning *****\n");
            //指向同一个对象的两个引用
              Point p1 = new Point(50, 50);
            Point p2 = p1;
            p2.X = 0;
            Console.WriteLine(p1);
            Console.WriteLine(p2);
            Console.ReadLine();
        }

结果:

 

 实现标准ICloneable接口,可以使自定义类型具有返回自身副本的能力。

public interface ICloneable
{
    object Clone();
}

 

当Point类中没有引用型数据成员时,可以直接MemberwiseClone()方法返回自身。

注意:MemberwiseClone()是System.Object的成员,这个方法是受保护的,对象用户不能直接调用这个方法,这个方法获取当前对象的一个“浅复制”。

// A class named Point.
    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)
        {
            X = xPos; Y = yPos;
        }
        public Point() { }

        // Override Object.ToString().
        public override string ToString()
        {
            return string.Format("X = {0}; Y = {1};", X, Y);
        }

        // Return a copy of the current object.
        public object Clone()
        {
            return this.MemberwiseClone();
         }
    }
static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with Object Cloning *****\n");
            Point p3 = new Point(100, 100);
            Point p4 = (Point)p3.Clone();

          
            p4.X = 0;

            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();
        }

 

 

当Point类中包含引用型数据成员时,我们就必须对Clone()方法做进一步修改。

    // A class named Point.
    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() { }

        // Override Object.ToString().
        public override string ToString()
        {
            return string.Format("X = {0}; Y = {1}; Name = {2};\nID = {3}\n",
              X, Y, desc.PetName, desc.PointID);
        }

        // Return a copy of the current object.
        // Now we need to adjust for the PointDescription member.
        public object Clone()
        {
            // First get a shallow copy.
            Point newPoint = (Point)this.MemberwiseClone();

            // Then fill in the gaps.
            PointDescription currentDesc = new PointDescription();
            currentDesc.PetName = this.desc.PetName;
            newPoint.desc = currentDesc;
            return newPoint;
        }
    }

    // This class describes a point.
    public class PointDescription
    {
        public string PetName { get; set; }
        public Guid PointID { get; set; }

        public PointDescription()
        {
            PetName = "No-name";
            PointID = Guid.NewGuid();
        }
    }
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 @ 2012-11-09 15:41  xulonghua219  阅读(271)  评论(0编辑  收藏  举报