[你必须知道的.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);
        }
    }
}

时间: 2024-10-26 18:11:02

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

[你必须知道的.Net]读书笔记--override与new在继承中的区别

前言:这本书拿到手已经好长时间了,但由于种种原因一直没读完,也许是我太懒了,应该好好反省自我检讨一下. 所谓"书读百遍,其义自见",虽然糊里糊涂做web开发六七年了,用.net也3年出头,但总觉得自己还是一个.net新手,很多东西只知道怎么用,但不知道为什么? 虽然老赵曾经讲过的一个观点我也很赞同,原话已经记不清了,大意是说:很多数学上的公理公式,只要前人(或自己)证明过是对的,以后再用时,谁会一次次的再重复去证明,直到证明结果弄对了再拿来用?但是有些问题还要是有比较深刻理解的,否则经

读书感受 - 软件设计师 - 你必须知道的.NET (C#类型存储方式分析)

      这几天花了些时间,相对仔细的阅读了<你必须知道的.NET>这本书,因为没有多少时间,请大家在看该书的时候一定要理解内容,转变成自己的经验.下面仅做简单的书评.         该书详细的介绍了C#类型的存储分配问题,对于值类型和引用类型的存储和类型的转换,都用了大篇幅来进行说明,如果还想再详细些,就得去看.net framework中的底层方法和机制了.其实它的这个存储分配,不该说是C#,应该是.net这个框架的存储分配方式.对于其它语言,比如VB.NET,VC++.NET也是一致

Canvas性能技巧:必须知道的Canvas性能技巧

文章简介:你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的! 你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的! 一.预渲染错误代码:       var canvas = document.getElementById

你必须知道的.NET

[你必须知道的.NET]第三十五回,判断dll是debug还是release,这 [你必须知道的.NET]第三十四回,object成员,不见了! [你必须知道的.NET]第三十一回,深入.NET 4.0之,从"新"展望 [你必须知道的.NET]第三十三回,深入.NET 4.0之,Lazy<T> [你必须知道的.NET]第三十二回,,深入.NET 4.0之,Tuple一二 [你必须知道的.NET]第三十回:.NET十年(下) [你必须知道的.NET]第二十九回:.NET十年(

[你必须知道的.NET]第二十七回:interface到底继承于object吗?

说在,开篇之前 在.NET世界里,我们常常听到的一句话莫过于"System.Object是一切类型的根,是所有类型的父类",以至于我在<你必须知道的.NET>8.1节 以"万物归宗:System.Object"这样的title为System.Object授予至高荣誉.所以,基于这样的观点就有了下面这句"接口是否也继承于System.Object?",事实上这正是今天在技术群里小小讨论的一个插曲. 1 缘起 在.NET世界里,我们常常听

[你必须知道的.NET]第二十四回:认识元数据和IL(上)

说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么迅速,但是Metadata和IL却是绝对重量级的内容,值得我们在任何时间关注,本文就是开始. 1 引言 你可曾想到,我们的C#代码,编译之后究竟为何物?你可曾认知,我们的可执行程序,运行之时的轨迹究竟为哪般?那么,本文通过对Metadata(元数据)和IL(Intermediate Language, 中间语

[你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考

走钢丝的人,在刺激中体验快感.带着问题思考,在问题上迸发火花. 或者给问题以答案,或者给答案以问题,你可能永远无法看清全部,但是总能从一点突破很多.事实的关键就在于面对问题,我该如何思考? String Interning(字符串驻留)就是这样一个值得思考的话题,带着问题思考,我们至少要理清以下几个问题: 什么是string? 什么是字符串驻留? 字符串驻留的运行机制及执行过程? 字符串驻留的其他问题? 带着几个问号,你必须知道的.NET,继续更多体验. 1 带着问题? 带着问题思考,是技术探索

[你必须知道的.NET]第二十回:学习方法论

说在,开篇之前 本文,源自我回答刚毕业朋友关于.NET学习疑惑的回复邮件. 本文,其实早计划在<你必须知道的.NET>写作之初的后记部分,但是因为个中原因未能如愿,算是补上本书的遗憾之一. 本文,作为[<你必须知道的.NET>]系列的第20回,预示着这个系列将开始新的征程,算是[你必须知道的.NET]2.0的开始. 本文,作为一个非技术篇章,加塞儿到<你必须知道的.NET>队伍中,我想至少因为回答了以下几个必须知道的非技术问题:.NET应该学习什么? .NET应该如何学

[你必须知道的.NET]第十四回:认识IL代码---从开始到现在

本文将介绍以下内容: ·IL代码分析方法 ·IL命令解析 ·.NET学习方法论 1.引言 自从『你必须知道.NET』系列开篇以来,受到大家很多的关注和支持,给予了anytao巨大的鼓励和动力.俱往昔,我发现很多的园友都把目光和焦点注意在如何理解IL代码这个问题上.对我来说,这真是个莫大的好消息,因为很明显我们的思路慢慢的从应用向底层发生着转变,技巧性的东西是一个方面的积累,底层的探索在我认为也是必不可少的修炼.如果我们选择了来关注这项修炼,那么我们就应该选择如何来着手这项修炼,首先关注anyta