在.net framework中,提供了ICloneable接口来对对象进行克隆。当然,你也可以不去实现ICloneable接口而直接自己定义一个Clone()方法,当然,还是推荐实现ICloneable接口。

具体实现方法

using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; [Serializable]
public class Job
{
public int id;
public string JobName { get; set; }
public override string ToString()
{
return this.JobName;
}
public int ID
{
get { return id;}
set { id = value;}
}
} [Serializable]
public class Person:ICloneable
{
public int Age { get; set; } //值类型字段
public string Name { get; set; } //字符串
public Job Job { get; set; } //引用类型字段 //深拷贝
public Person DeepClone()
{
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream,this);
objectStream.Seek(, SeekOrigin.Begin);
return formatter.Deserialize(objectStream) as Person;
}
} public object Clone()
{
return this.MemberwiseClone(); //浅拷贝
} //浅拷贝
public Person ShallowClone()
{
return this.Clone() as Person;
}
}

测试案例:

using UnityEngine;
using System.Collections; //测试C# 类拷贝
public class ClassCloneTest : MonoBehaviour { // Use this for initialization
void Start ()
{
Person p = new Person() { Name = "test0001", Age = ,Job = new Job(){JobName="Coder",ID = } }; string Str = ""; Str = string.Format("修改前:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName); Person p1 = p.ShallowClone();
Person p2 = p.DeepClone(); Debug.Log(Str);
Str = string.Format("修改前:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);
Debug.Log(Str);
Str = string.Format("修改前:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);
Debug.Log(Str); //修改p的所有字段值
Debug.Log("修改P1的值: ");
p1.Name = "test000222222";
p1.Age = ;
p1.Job.JobName = "Manager";
p1.Job.ID = ; Str = string.Format("修改后:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);
Debug.Log(Str);
Str = string.Format("修改后:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);
Debug.Log(Str);
Str = string.Format("修改后:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);
Debug.Log(Str);
}
}

结果输出:

  

结论:

  这个结果可以看出,浅表副本和原始副本并不是一个对象,但是,浅表副本复制了原始对象的值类型和string类型,但是数组只复制了引用。

这个现象很有趣,按照MSDN的定义:“MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。

如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。”,

  但是,在实际上,string应该也是引用类型,但是,浅表副本却复制了这个值。

  无论是浅拷贝与深拷贝,C#都将源对象中的所有字段复制到新的对象中。不过,对于值类型字段,引用类型字段以及字符串类型字段的处理,两种拷贝方式存在一定的区别(见下表)。

  

参考: http://visionsky.blog.51cto.com/blog/733317/237917

    http://blog.csdn.net/yl2isoft/article/details/12200513

C#对象复制 ICloneable的更多相关文章

  1. [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2

    接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...

  2. PHP基础知识之对象复制

    对象的复制默认为浅复制 进行深复制的方法为:在类中定义魔法方法__clone(),类的对象复制时,会自动调用 __clone方法,在 __clone方法中可以进行各种复制对象的个性化 class My ...

  3. JS对象复制

    在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...

  4. PHP写时复制, 变量复制和对象复制不同!!!

    2016年3月18日 15:09:28 星期五 一直以为PHP对象也是写时复制....... 其实: PHP的变量是写时复制, 对象是引用的 写时复制: $a = $b; 如果$b的内容不改变, $a ...

  5. 【转】JavaScript中的对象复制(Object Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...

  6. 对象复制、克隆、深度clone

    -------------------------------------------------------------------------------- ------------------- ...

  7. PHP5的对象复制

    今天用yii开发程序,一个bug改了一晚上,最后发现问题出在了对象复制机制上,PHP5之前的对象复制只需要$object_a = $object_b即可,但PHP5这样得到的是浅复制,及指针指向,并不 ...

  8. Java反射 - 2(对象复制,父类域,内省)

    为什么要复制对象?假设有个类Car,包含name,color2个属性,那么将car1对象复制给car2对象,只需要car2.setName(car1.getName)与car2.setColor(ca ...

  9. js原生设计模式——7原型模式之真正的原型模式——对象复制封装

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

随机推荐

  1. android中的HttpURLConnection和HttpClient实现app与pc数据交互

    自学android的这几天很辛苦,但是很满足,因为每当学到一点点知识点都会觉得很开心,觉得今天是特别有意义的,可能这个就是一种莫名的热爱吧. 下面来说说今天学习的HttpURLConnection和H ...

  2. openstack Icehouse发布

    OpenStack 2014.1 (Icehouse) Release Notes General Upgrade Notes Windows packagers should use pbr 0.8 ...

  3. kd tree学习笔记 (最近邻域查询)

    https://zhuanlan.zhihu.com/p/22557068 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 KD树 ...

  4. static(静态、修饰符)

    static(静态.修饰符) static修饰成员变量时:static修饰成员变量时,那么该成员变量的数据就是一个共享的数据. 静态成员变量的访问方式: 方式一: 使用对象进行访问. 对象.属性名 方 ...

  5. Knockout学习笔记之一

    1.  四大关键理念: A. DeclarativeBindings(声明式绑定) Easily associate DOM elements with model data using a conc ...

  6. [原创] RT7 Lite win7旗舰版精简方案

    [原创] RT7 Lite win7旗舰版精简方案 墨雪SEED 发表于 2016-1-26 21:23:54  https://www.itsk.com/thread-362912-1-5.html ...

  7. C/C++ 如何来自动优雅的涮别银家的贴子

    被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码.下面,来淘淘这份经验,呼呼 我们要了解Web browser 这个控件,因为到 ...

  8. openwrt 的依赖找不到问题

    Openwrt报告库找不到Package * is missing dependencies for the following libraries: libc.so.6 或其他先检查系统里面有没有这 ...

  9. Windows C++ 子目录数量

    CFileFind OneFile; BOOL bWorking = FALSE; ; ) != "\\") { strPath += "\\*.*"; } b ...

  10. w3school一个学习编程的好地方!

    http://www.w3school.com.cn/index.html 每天过来学习几篇.