C#对象复制 ICloneable
在.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的更多相关文章
- [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2
接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...
- PHP基础知识之对象复制
对象的复制默认为浅复制 进行深复制的方法为:在类中定义魔法方法__clone(),类的对象复制时,会自动调用 __clone方法,在 __clone方法中可以进行各种复制对象的个性化 class My ...
- JS对象复制
在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...
- PHP写时复制, 变量复制和对象复制不同!!!
2016年3月18日 15:09:28 星期五 一直以为PHP对象也是写时复制....... 其实: PHP的变量是写时复制, 对象是引用的 写时复制: $a = $b; 如果$b的内容不改变, $a ...
- 【转】JavaScript中的对象复制(Object Clone)
JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...
- 对象复制、克隆、深度clone
-------------------------------------------------------------------------------- ------------------- ...
- PHP5的对象复制
今天用yii开发程序,一个bug改了一晚上,最后发现问题出在了对象复制机制上,PHP5之前的对象复制只需要$object_a = $object_b即可,但PHP5这样得到的是浅复制,及指针指向,并不 ...
- Java反射 - 2(对象复制,父类域,内省)
为什么要复制对象?假设有个类Car,包含name,color2个属性,那么将car1对象复制给car2对象,只需要car2.setName(car1.getName)与car2.setColor(ca ...
- js原生设计模式——7原型模式之真正的原型模式——对象复制封装
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
随机推荐
- SSH项目Class类的注解与属性的注解
经过一段日子对SSH的学习,为了有利于随时能熟练的把一个SSH的项目快速的搭建起来,并且在报错的时候,将报错信息和解决 方案记录下来,每天一次的代码练习已成为家常便饭 所以,在反复练习的时候,发现Sp ...
- hasOwnProperty,in
hasOwnProperty,in区别: hasOwnProperty:指出一个对象是否具有指定名称的属性 in:对象是否能够访问此属性(包括直接在对象上访问和通过原型访问) 看下示例代码: (fun ...
- css样式设计
1.行内元素(图片.文本)水平居中 通过给父元素设置 text-align:center html代码: <body> <div class="txtCenter" ...
- Java—类的封装、继承与多态
一.类和对象 1.类 类是数据以及对数据的一组操作的封装体. 类声明的格式: 类声明 { 成员变量的声明: 成员方法的声明及实现: } 1.1 声明类 [修饰符] class 类<泛型> ...
- HTML5的 2D SVG和SVG DOM的学习笔记(2)---SVG动画
SVG支持动画.可以通过以下几种方法获得动画效果: 使用SVG动画元素.SVG可以描述随时间变化的图形对象,使用不同的动画元素可以定义运动路径,淡入淡出效果和对象的膨胀.收缩.旋转和变换颜色. 使用S ...
- PHP中多态,抽象类,接口,
小例子: 需求:公司定义一个接口让我们开发功能 usb.interface.php: <?php interface USB{ public function run(); } store.cl ...
- iOS开发UI篇—无限轮播(循环利用)
iOS开发UI篇—无限轮播(循环利用) 一.无限轮播 1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollV ...
- Rhel6-sersync配置文档
系统环境: rhel6 x86_64 iptables and selinux disabled 主服务器: 192.168.122.160 server60.example.com 目标服务器: 1 ...
- DOM扩展之Selectors API
jQuery的核心就是通过CSS选择符查询DOM文档取得元素的引用,从而抛开了getElementById()和getElementsByTagName(). Selectors API致力于让浏览器 ...
- Java String字符串补0或空格
package cn.com.songjy; import java.text.NumberFormat; //Java 中给数字左边补0 public class NumberFormatTest ...