构建可克隆的对象(ICloneable)
ICloneable接口
如果想使自己的自定义类型支持向调用方返回自身同样副本的能力,需要实现标准ICloneable接口。
namespace System
{ public interface ICloneable
{
object Clone();
}
}
浅拷贝
System.Object定义了一个名为MemberwiseClone()的成员。这个方法用来获取当前对象的一份浅拷贝。
例:
Point.cs
namespace CloneablePoint
{
// The Point now supports "clone-ability."
public class Point : ICloneable
{
public int X { get; set; }
public int Y { get; set; }
public PointDescription desc = new PointDescription(); public Point( int xPos, int yPos, string petName )
{
X = xPos; Y = yPos;
desc.PetName = petName;
}
public Point( int xPos, int yPos )
{
X = xPos; Y = yPos;
}
public Point() { } // Override Object.ToString().
public override string ToString()
{
return string.Format("X = {0}; Y = {1}; Name = {2};\nID = {3}\n",
X, Y, desc.PetName, desc.PointID);
} // Return a copy of the current object.
// Now we need to adjust for the PointDescription member.
public object Clone()
{
// 这个复制每个Ponit字段成员
Point newPoint = (Point)this.MemberwiseClone();
return newPoint;
}
}
}
PointDescription.cs
namespace CloneablePoint
{
// This class describes a point.
public class PointDescription
{
public string PetName { get; set; }
public Guid PointID { get; set; } public PointDescription()
{
PetName = "No-name";
PointID = Guid.NewGuid();
}
}
}
Program.cs
namespace CloneablePoint
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Fun with Object Cloning *****\n");
Console.WriteLine("Cloned p3 and stored new Point in p4");
Point p3 = new Point(, , "Jane");
Point p4 = (Point)p3.Clone(); Console.WriteLine("Before modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
p4.desc.PetName = "My new Point";
p4.X = ; Console.WriteLine("\nChanged p4.desc.petName and p4.X");
Console.WriteLine("After modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
Console.ReadLine();
}
}
}

请注意,如果Ponint包含任何引用类型成员变量,MemberwiseClone()将这些引用复制到对象中(即浅复制)。如果想要支持真正的深复制,需要在克隆过程中创建任何引用类型变量的新实力。
深拷贝
Point.cs
namespace CloneablePoint
{
public class Point : ICloneable
{
public int X { get; set; }
public int Y { get; set; }
public PointDescription desc = new PointDescription(); public Point( int xPos, int yPos, string petName )
{
X = xPos; Y = yPos;
desc.PetName = petName;
}
public Point( int xPos, int yPos )
{
X = xPos; Y = yPos;
}
public Point() { } public override string ToString()
{
return string.Format("X = {0}; Y = {1}; Name = {2};\nID = {3}\n",
X, Y, desc.PetName, desc.PointID);
} public object Clone()
{
Point newPoint = (Point)this.MemberwiseClone(); PointDescription currentDesc = new PointDescription();
currentDesc.PetName = this.desc.PetName;
newPoint.desc = currentDesc;
return newPoint;
}
}
}
PointDescription.cs
namespace CloneablePoint
{
public class PointDescription
{
public string PetName { get; set; }
public Guid PointID { get; set; } public PointDescription()
{
PetName = "No-name";
PointID = Guid.NewGuid();
}
}
}
Program.cs
namespace CloneablePoint
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Fun with Object Cloning *****\n");
Console.WriteLine("Cloned p3 and stored new Point in p4");
Point p3 = new Point(, , "Jane");
Point p4 = (Point)p3.Clone(); Console.WriteLine("Before modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
p4.desc.PetName = "My new Point";
p4.X = ; Console.WriteLine("\nChanged p4.desc.petName and p4.X");
Console.WriteLine("After modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
Console.ReadLine();
}
}
}

构建可克隆的对象(ICloneable)的更多相关文章
- ES5-ES6-ES7_字符串与JOSN格式的数据相互转换以及深度克隆新对象
这篇文章主要来讲HTML5中的新方法:parse()把字符串转换成josn格式的数据和stringify()把josn格式的数据转换成字符串 eval()方法的回顾 eval()方法可以将任何字符串解 ...
- JavaScript面向对象编程(10)高速构建继承关系之对象拷贝
前面的样例我们是通过构造器创建对象.而且希望该对象继承来自另外一个构造器的对象 我们也能够直接面向一个对象来达成继承的目的.使用下属步骤: 1.拷贝一个对象 2.给新对象加入属性 /** * 通过拷贝 ...
- 利用BeanUtils.copyProperties 克隆出新对象,避免对象重复问题
1.经常用jQuery获取标签里面值val(),或者html(),text()等等,有次想把获取标签的全部html元素包括自己也用来操作,查询了半天发现$("#lefttr1"). ...
- XAF ORMDataModel构建的基础资料对象无法被调用显示的解决办法
修正,其实只要在基础资料类中加入[XafDefaultProperty("名称")]标签即可. namespace NEO.ERP.Module.BusinessObjects.B ...
- ES6 克隆对象 浅克隆:只能克隆原始对象自身的值,不能克隆它继承的值
https://www.cnblogs.com/xbblogs/p/8954165.html return JSON.parse(JSON.stringify(origin)) 最早由Barbara ...
- 深度克隆(对象、数组)--------百度IFE前端task2
var srcObj = { a: 1, b: { b1: ["hello", "hi"], b2: "JavaScript" }}; co ...
- 在JAVASCRIPT中构建一个复杂的对象,并用JSON进行转换
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 精通C#(第6版)
<精通C#(第6版)> 基本信息 原书名:Pro C# 5.0 and the .NET 4.5 framework,sixth edition 作者: (美)Andrew Troelse ...
- .NET 接口
接口 接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...
随机推荐
- 简析LIVE555中的延时队列
http://www.cnblogs.com/nightwatcher/archive/2011/04/10/2011158.html 最近在看LIVE555的源码,感觉其中的延时队列写的不错,于是就 ...
- Android中的六大布局
继承关系图: 布局XML文件中常用属性: android:layout_width 宽度 android:layout_height 高度 可能的取值为match_parent,wrap_conte ...
- redis key和value数据类型
exists key del key1 key2 Redis 的vauleredis 提供五种数据类型:string,hash,list,set 及sorted set. string 是最基本的类型 ...
- 【HDOJ】1031 Design T-Shirt
qsort直接排序. #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXN ...
- [ZOJ 3623] Battle Ships
Battle Ships Time Limit: 2 Seconds Memory Limit: 65536 KB Battle Ships is a new game which is s ...
- MOSS母板页制作 学习笔记(一)
转:http://xiachanghao1990.blog.163.com/blog/static/4869602420114235536573/ 母版页制作其实应该算是一个比较基础的工作,但是熟练制 ...
- HDU- Who Gets the Most Candies?
Who Gets the Most Candies? Time Limit : 10000/5000ms (Java/Other) Memory Limit : 262144/131072K (J ...
- 理解c++11正则表达式 (1)
概要 C++11提出了正则表达式这个概念,只需在头文件中包含#include<regex>即可.我们可以完成: Match 将整个输入拿来比对匹配某个正则表达式 Search 查找与正则表 ...
- js函数参数设置默认值
php有个很方便的用法是在定义函数时可以直接给参数设默认值,如: function simue ($a=1,$b=2){ return $a+$b;}echo simue(); //输出3echo ...
- tomcat详细日志配置
在server.xml里的<host>标签下加上<Valve className="org.apache.catalina.valves.AccessLogValve&qu ...