.NET基础之深度复制和浅度复制

之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉。

大家都知道Object是所有类共同的基类,其有个方法是MemberwiseClone(),其用途为

我们可以通过这个方法来达到浅度复制的效果。

下面我们通过一个例子来阐述一下浅度复制,其与深度复制的区别在什么地方:

public class Content
    {
        public int Val;
    }
    public class Cloner
    {
        public Content MyContent = new Content();

        public Cloner(int newVal)
        {
            MyContent.Val = newVal;
        }
        public object GetCopy()
        {
            return MemberwiseClone();
        }
    }

在这里我们有两个类,一个Content类,只有一个为值类型int的Val,还有个类是一个Cloner类,其有一个Content类型的成员,然后有个构造函数可以初始化成员,最后有一个GetCopy的方法,通过MemberwiseClone方法来复制自己。

下面我们通过一段代码来调用Cloner类:

static void Main(string[] args)
        {
            Cloner source = new Cloner(10);
            Cloner target = (Cloner)source.GetCopy();//返回的是一个Object类型 需要做类型转换.
            Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
            source.MyContent.Val = 15;
            Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
            Console.ReadKey();
        }

结果是:

我们可以看到我们通过GetCopy()函数复制类source给target,但是当我们改变source的时候,source输出的值也跟着改变。由此我们可以得出,我们通过MemberwiseClone()复制的只是引用,即source和target的MyContent是相同的对象实例。这就是浅度复制,那我们如何实现深度复制呢,在.NET Framework中,给我们提供了ICloneable接口。

首先我们看下ICloneable接口:

// 摘要:
    //     支持克隆,即用与现有实例相同的值创建类的新实例。
    [ComVisible(true)]
    public interface ICloneable
    {
        // 摘要:
        //     创建作为当前实例副本的新对象。
        //
        // 返回结果:
        //     作为此实例副本的新对象。
        object Clone();
    }

在上面那个例子中,我们只需要修改一些代码就可以了:

public class Cloner:ICloneable
    {
        public Content MyContent = new Content();

        public Cloner(int newVal)
        {
            MyContent.Val = newVal;
        }
        //public object GetCopy()
        //{
        //    return MemberwiseClone();
        //}
        public object Clone()
        {
            Cloner cloned = new Cloner(MyContent.Val);
            return cloned;
        }
    }

为了做区别我把之前的代码放在上面,注释了的代码就是浅度复制,后面的为深度复制,我们看到差别在于用本实例的MyContent.Val重新生成了实例返回给目标,测试结果为:

这里如果MyContent的成员不是一个值类型,那么我们还需要进行深度,像下面一样:

public object Clone()
        {
            Cloner cloned = new Cloner();
            cloned.MyContent = MyContent.Clone();
            return cloned;
        }

深度复制和浅度复制就是这样,关键是创建一个新的对象实例返回去,而不是把原来的对象实例返回回去。大家懂了吗?

时间: 2024-07-30 18:06:44

.NET基础之深度复制和浅度复制的相关文章

深度复制与浅度复制

浅度复制:只是复制类的值类型字段和引用类型字段的引用 深度复制:即完全复制过来,不管里面的值类型字段还是引用类型字段,是构成一个全新的一模一样的对象. 代码: 1 public class PersonInfo 2 { 3 public string Name{get;set;} 4 public int Age{get;set;} 5 } 6 public class Person : ICloneable 7 { 8 public PersonInfo PersonInfo { get; s

转载---Java集合对象的深度复制与普通复制

原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复制的区别. 1.首先是对Java集合对象得浅复制与深度复制的理解 普通的集合复制只是将内存中栈的地址快拷贝一份,使得一个新的集合对象指向这个地址块,但是集合中的对象变量却是指向堆中的同一块区域.所以当拷贝的集合修改了集合对象内的数据,那么源集合对象也就随之改变了,这样的效果我们称之为Java集合对象

浅度复制VS深度复制

对于引用类型的复制,通过MemberwiseClone()复制的只是引用,即myclone1和myclone2的myContent是相同的对象实例.一个改变值,另一个也会改变.因为myContent.Val是公共字段. 值对象则没有这种顾虑 PS:感觉ICloneable 接口并没有什么用,完全可以自己写方法.毕竟ICloneable里面只有一个Clone方法. 代码如下: 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 C

类的浅度复制和深度复制

现在我们定义一个类 //name.h class name { private: char *str; int len; static in num_name; //全局变量,不能在声明中初始化.(因为声明描述了如何分配内存,但不分配内存). public: name(); name(const char* s); name(const name& s); ~name(); } //name.cpp #include <cstring> #include <iostream>

深度解析javascript中的浅复制和深复制

原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型.而Object又包含Function,Array和Object自身.前面的五种类型叫做基本类型,而Object是引用类型.可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的. 我们首先来看看浅复制和深复制的简洁定义: 深复制:直接将数据复制给

python基础之浅复制与深复制

关于列表.字典.元组的浅复制和深复制,数字和字符串没有浅复制和深复制一说.下面我直接用代码来体现: 1 import copy 2 3 names = ['Cahill','Teenglan','Eric','Peggie','Aalto','Baal','Sadie', 4 'Gage','Hagan','Jack','Kaley','Mabel','Lacy','Nadine','Pace','Amy'] 5 6 #浅复制 7 names2 = names.copy() 8 names2[1

C++学习基础七——深复制与浅复制

一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深复制时,A中的指针str与B中的指针str指向不同的地址,只是地址所指向的数据相同. 当浅复制时,A中的指针str与B中的指针str指向相同的地址. 1.浅复制:如果我们自己不实现复制构造函数,则C++会自动合成一个复制构造函数,又称为浅复制构造函数. 2.深复制:如果使用指针或者系统资源(如数据库

java基础-浅复制与深复制的理解

浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等.我们可以发现,复制操作后可以得到两份相同的东西,即复制由一变为二了.下面来看一个例子: public class User{ private int age; public int getAge(){ return age; } } User user1 = new User(); User us

也来谈一谈js的浅复制和深复制

1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,undefined,string,number和boolean),这些类型的值本身就存储在栈内存中(string类型的实际值还是存储在堆内存中的,但是js把string当做基本类型来处理 ),不存在引用值的情况. 浅复制和深复制都可以实现在已有对象的基础上再生一份的作用,但是对象的实例是存储在堆内存中然后通