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

  • 相关阅读:
    基于正方系统的抢课软件教程系列一模拟登录1
    基于正方系统的抢课软件教程系列二正则表达式使用
    基于正方系统的抢课软件教程系列一模拟登录3之验证码识别
    eCos中断模型
    eCos下针对MIPS指令集的backtrace
    开源许可证GPL
    获取ListView中的ImageButton
    Rancher v2.4.8 容器管理平台集群搭建(基于k8s)
    Linux awk 替换文本字符串内容
    go: go.mod file not found in current directory or any parent directory; see 'go help mod 解决
  • 原文地址:https://www.cnblogs.com/hellolong/p/2762755.html
Copyright © 2011-2022 走看看