c# 深拷贝与浅拷贝的区别分析及实例

深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等。

浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。

C#中有两种类型变量,一种 是值类型变量,一种是引用类型变量。对于前者,copy是属于全盘复制;而对于后者,一般的copy只是浅copy,相当于只传递一个引用指针一样。因此 对于后者进行真正copy的时候,也是最费事的,具体的说,必须为其实现ICloneable接口中提供的Clone方法。

看看定义:
      浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用.
      深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.

浅拷贝和深拷贝的区别
      浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象 中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一 个新的和原是对象中对应字段相同(内容相同)的字段,也就是说这个引用和原是对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对 象中对应字段的内容。所以对于原型模式也有不同的两种处理方法:对象的浅拷贝和深拷贝。

下面通过实例可以清楚看到浅拷贝与深拷贝的区别,代码如下:

代码如下:

using System;
 using System.Collections.Generic;
 using System.Text;

namespace WindowsApplication1
 {
     class Program
     {
         public class Sex
         {
             private string _PSex;
             public string PSex
             {
                 set
                 {
                     _PSex = value;
                 }
                 get
                 {
                     return _PSex;
                 }
             }

}

public class Person : ICloneable
         {

private Sex _pSex = new Sex();
             public int aa = 1213;

public string pSex
             {
                 set
                 {
                     _pSex.PSex = value;
                 }
                 get
                 {
                     return _pSex.PSex;
                 }
             }
             private string _PName;
             public string PName
             {
                 set
                 {
                     this._PName = value;
                 }
                 get
                 {
                     return this._PName;
                 }
             }

public void ShowPersonInfo()
             {
                 Console.WriteLine("-------------------------");
                 Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex);
                 Console.WriteLine("-------------------------");
                 Console.WriteLine(this.aa);
             }
             //浅拷贝
             public object Clone()
             {
                 return this.MemberwiseClone();
             }
             //深拷贝
             public object DeepClone()
             {
                 Person newP = new Person();
                 newP.PName = this._PName;
                 newP.pSex = this.pSex;
                 return newP;
             }

}

static void Main(string[] args)
         {
             Console.WriteLine("原对象:");
             Person p = new Person();
             p.PName = "JackLee";
             p.pSex = "男";

p.ShowPersonInfo();

//浅拷贝       
             Person copy = (Person)p.Clone();
             //深拷贝
             Person dcopy = (Person)p.DeepClone();

Console.WriteLine("修改后的原对象:");
             p.PName = "JackZhao";
             p.pSex = "女";
             p.aa = 1111;
             p.ShowPersonInfo();

Console.WriteLine("修改后的浅拷贝对象:");
             copy.ShowPersonInfo();
             Console.WriteLine("修改后的深拷贝对象:");
             dcopy.ShowPersonInfo();

Console.WriteLine("直接拷贝对象:");
             Person PP = p;
             PP.ShowPersonInfo();

Console.ReadLine();

}

}
 }

好了,关于深拷贝与浅拷贝就说到这里,项目还没完事,先抓紧了。代码可以直接复制到项目中运行。

(0)

相关推荐

  • C#实现windows form拷贝内容到剪贴板的方法

    本文实例讲述了C#实现windows form拷贝内容到剪贴板的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Data; using System.Windows.Forms; public class MainClass { public static void Main(string[

  • C#浅拷贝和深拷贝实例解析

    在有些时候,我们需要从数据库读取数据填充对象或从硬盘读取文件填充对象,但是这样做相对耗时.这时候我们就想到了对象的拷贝.本文即以实例形式解析了C#浅拷贝和深拷贝的用法.具体如下: 一.浅拷贝 1.什么是"浅拷贝": 当针对一个对象前拷贝的时候,对于对象的值类型成员,会复制其本身,对于对象的引用类型成员,仅仅复制对象引用,这个引用指向托管堆上的对象实例. 2.有一个对象,包含引用类型的类成员和值类型的struct成员 Cinema包含引用类型成员Room和值类型成员Film. publi

  • c#深拷贝文件夹示例

    复制代码 代码如下: using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Text.RegularExpressions;using System.Threading.Tasks; namespace FileUtility{    public class Program    {        public static v

  • C#通过指针实现快速拷贝的方法

    本文实例讲述了C#通过指针实现快速拷贝的方法.分享给大家供大家参考.具体实现方法如下: // fastcopy.cs // 编译时使用:/unsafe using System; class Test { // unsafe 关键字允许在下列 // 方法中使用指针: static unsafe void Copy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int count) { if (src == null || srcIndex

  • C#运用FileInfo类实现拷贝文件的方法

    本文所述实例为C#运用FileInfo类实现拷贝文件的方法,程序中C#首先创建一个 StreamWriter 对象 writer,它向 FileInfo 的实例 srcFile 所表示的文件追加文本,FileInfo 类的 CopyTo 方法,实现文件的拷贝. 具体实现代码如下: using System; using System.IO; namespace 拷贝文件 { class Class1 { [STAThread] static void Main(string[] args) {

  • 简单谈谈C#中深拷贝、浅拷贝

    Object.MemberwiseClone 方法 创建当前 Object 的浅表副本. protected Object MemberwiseClone() MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象. 如果字段是值类型的,则对该字段执行逐位复制. 如果字段是引用类型,则复制引用但不复制引用的对象:因此,原始对象及其复本引用同一对象. 例如,考虑对象X引用对象 A 和 B , 对象 B 依次引用对象 C. X 的浅表副本

  • C# 拷贝数组的几种方法(总结)

    突然学到了,所以就放到博客上来共享一下,权当是学习日记吧. 首先说明一下,数组是引用类型的,所以注意不要在复制时复制了地址而没有复制数值哦! 其实在复制数组的时候,一定要用new在堆中开辟一块新的空间专门用于存放数组,这样才是有效的. (1) int[] pins = { 9, 3, 7, 2 }; int[] copy=new int[pins.length]; for (int i = 0; i < copy.length; i++) { copy[i] = pins[i]; } (2) i

  • C#实现屏幕拷贝的方法

    本文实例讲述了C#实现屏幕拷贝的方法.分享给大家供大家参考.具体如下: 方法一: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace Wi

  • C#拷贝文件简单实现方法

    本文实例讲述了C#拷贝文件简单实现方法.分享给大家供大家参考.具体分析如下: C#中拷贝文件可以先通过FileInfo指定文件,然后通过FileInfo的CopyTo方法拷贝文件到指定的位置 FileInfo fi = new FileInfo(@"C:\file.txt"); if(fi.Exists) { fi.CopyTo(@"C:\copyfile.txt"); } 希望本文所述对大家的C#程序设计有所帮助.

  • C#中4种深拷贝方法介绍

    1:利用反射实现 public static T DeepCopy<T>(T obj) { //如果是字符串或值类型则直接返回 if (obj is string || obj.GetType().IsValueType) return obj; object retval = Activator.CreateInstance(obj.GetType()); FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | B

随机推荐