zoukankan      html  css  js  c++  java
  • 构建可克隆的对象(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};
    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();
            }
        }
    }

  • 相关阅读:
    [Javascript] twitterbootstrap: 解决2.1版本中modal加载远程内容时,只加载一次的问题
    向大型网站学习SEO优化之道
    [Yii Framework] 使用Yii Framework开发微信公众平台
    [jQuery] ajax跨域处理方式
    [jQuery] form提交到iframe之后,获取iframe里面内容
    [Ubuntu] fatal: recursion detected in die handler
    [Yii Framework] Yii如何实现前后台的session分离
    [ubuntu] ubuntu13.04 64bit,安装FastDFS4.06过程遇到的问题和解决方案
    [转] 怎样在Ubuntu上安装Git服务器
    [ubuntu] ubuntu13.04切换桌面/工作区的方法
  • 原文地址:https://www.cnblogs.com/gyt-xtt/p/6265262.html
Copyright © 2011-2022 走看看