[你必须知道的.Net]读书笔记--浅clone与深clone

按照书上的代码,深克隆的示例代码编译没通过(可能是印刷时漏掉了某一行代码),所以重新修改了下,贴在这里以供阅读本书时跟我遇到一样问题的园友参考:

浅克隆示例: 要点:克隆之后,新旧对象还是指向同一个引用,不管修改哪一个对象,都会影响另一个对象

namespace CloneTest
{
 class Program
    {
 static void Main(string[] args)
        {          

            Enrollment sourceStudentsList = new Enrollment();
            sourceStudentsList.students.Add(new Student() { Name = "王小二", Age = 27 });
            sourceStudentsList.students.Add(new Student() { Name = "张三", Age = 22 });

            Enrollment cloneStudentsList = sourceStudentsList.Clone() as Enrollment;

            sourceStudentsList.ShowEnrollmentInfo("source");
            Console.WriteLine("----------------------------------------------------------------");
            cloneStudentsList.ShowEnrollmentInfo("clone");

            cloneStudentsList.students[1].Name = "李四";
            cloneStudentsList.students[1].Age = 36;
 
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("浅clone之后,修改clone对象将影响source对象");
            Console.WriteLine("----------------------------------------------------------------");
            sourceStudentsList.ShowEnrollmentInfo("source");
            Console.WriteLine("----------------------------------------------------------------");
            cloneStudentsList.ShowEnrollmentInfo("clone");

            Console.ReadLine();
        }
    }


 class Student
    {
 public string Name { set; get; }
 public Int32 Age { set; get; }
 

 public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }


 class Enrollment : ICloneable 
    {
 public List<Student> students = new List<Student>();

 public void ShowEnrollmentInfo(string Prefix) {
            Console.WriteLine(Prefix + " Students enrollment infomation:");
 foreach (Student s in students)
            {
                s.ShowInfo();
            }
        }       

 public object Clone() {
 return MemberwiseClone();
        }
    }
}

深克隆示例:

要点:深克隆要求完成克隆后,不管如何设置克隆出的新对象,都不会影响源对象(即新旧对象完全不相干)

using System;
using System.Collections.Generic;

namespace CloneTest
{
 class Program
    {
 static void Main(string[] args)
        {          

            Enrollment sourceStudentsList = new Enrollment();
            sourceStudentsList.students.Add(new Student() { Name = "王小二", Age = 27 });
            sourceStudentsList.students.Add(new Student() { Name = "张三", Age = 22 });


            Enrollment cloneStudentsList = sourceStudentsList.Clone() as Enrollment;

            sourceStudentsList.ShowEnrollmentInfo("source");
            Console.WriteLine("----------------------------------------------------------------");
            cloneStudentsList.ShowEnrollmentInfo("clone");

            cloneStudentsList.students[1].Name = "李四";
            cloneStudentsList.students[1].Age = 36;
 
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("深clone之后,修改clone对象不影响source对象");
            Console.WriteLine("----------------------------------------------------------------");
            sourceStudentsList.ShowEnrollmentInfo("source");
            Console.WriteLine("----------------------------------------------------------------");
            cloneStudentsList.ShowEnrollmentInfo("clone");

            Console.ReadLine();
        }
    }


 class Student
    {
 public string Name { set; get; }
 public Int32 Age { set; get; }
 

 public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }


 class Enrollment : ICloneable 
    {
 public List<Student> students = new List<Student>();

 public void ShowEnrollmentInfo(string Prefix) {
            Console.WriteLine(Prefix + " Students enrollment infomation:");
 foreach (Student s in students)
            {
                s.ShowInfo();
            }
        }

 //提供一个默认的公有构架函数,以保证Enrollment sourceStudentsList = new Enrollment();能正常编译通过
 public Enrollment() { }

 /// <summary>
 /// 提供了一个私有构造函数
 /// </summary>
 /// <param name="studentList"></param>
 private Enrollment(List<Student> studentList) 
        {
 foreach (Student s in studentList)
            {
                students.Add(new Student() { Name = s.Name, Age = s.Age });//注:原书P309的代码students.Add((Student)s.Clone());编译通不过--提示Student没有Clone方法,所以换成了这个
            }
        }

 public object Clone() {
 return new Enrollment(students);
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魂祭心

原 Expression Trees学习

29550
来自专栏码农阿宇

C#简单工厂和抽象类的实例

using System; using System.Collections.Generic; using System.Diagnostics; using ...

24840
来自专栏魂祭心

原 二叉树 非递归 层序、前序、中序、后序

32340
来自专栏菩提树下的杨过

ruby学习笔记(3)--语法层面的先见之明

看了几天ruby,发现c#中很多一直被称道的语法特性,ruby早在几年前就有了:  1.c#中的params关键字 class Program ...

22550
来自专栏菩提树下的杨过

Linq之ToDictionary<TSource, TKey, TElement>的写法

以前一直用 var query = xxx.Select(c=>new {c.X,c.Y}); 来取表中的某二列字段,今天有个应用需要转成Dictionary<...

232100
来自专栏along的开发之旅

C#中字符,字符串的大小写转换

对字符串来说,"string".ToLower()和"string".ToUpper()可以基本满足需求,但是当需要将首字母大写的时候,这两个函数就有点不够用了...

11210
来自专栏C/C++基础

ToString截取字符串的用法

string test1=test.ToString("F");//结果为343392590725.68,保留小数点后两位

10620
来自专栏landv

excel_VB宏脚本_批量生成点餐宝接受的格式

20120
来自专栏菩提树下的杨过

ArraySegment<T>泛型结构示例

以下代码利用ArrarSegment泛型结构,从int数组arr中取出arr[2]到arr[5] using System; using System.Col...

211100
来自专栏林德熙的博客

C# 复制列表

List<Fex> b = a.ToList(); 可以把列表a到列表b,对b进行删除、添加,不会对a造成元素改变。

16510

扫码关注云+社区

领取腾讯云代金券