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)的更多相关文章

  1. ES5-ES6-ES7_字符串与JOSN格式的数据相互转换以及深度克隆新对象

    这篇文章主要来讲HTML5中的新方法:parse()把字符串转换成josn格式的数据和stringify()把josn格式的数据转换成字符串 eval()方法的回顾 eval()方法可以将任何字符串解 ...

  2. JavaScript面向对象编程(10)高速构建继承关系之对象拷贝

    前面的样例我们是通过构造器创建对象.而且希望该对象继承来自另外一个构造器的对象 我们也能够直接面向一个对象来达成继承的目的.使用下属步骤: 1.拷贝一个对象 2.给新对象加入属性 /** * 通过拷贝 ...

  3. 利用BeanUtils.copyProperties 克隆出新对象,避免对象重复问题

    1.经常用jQuery获取标签里面值val(),或者html(),text()等等,有次想把获取标签的全部html元素包括自己也用来操作,查询了半天发现$("#lefttr1"). ...

  4. XAF ORMDataModel构建的基础资料对象无法被调用显示的解决办法

    修正,其实只要在基础资料类中加入[XafDefaultProperty("名称")]标签即可. namespace NEO.ERP.Module.BusinessObjects.B ...

  5. ES6 克隆对象 浅克隆:只能克隆原始对象自身的值,不能克隆它继承的值

    https://www.cnblogs.com/xbblogs/p/8954165.html return JSON.parse(JSON.stringify(origin)) 最早由Barbara ...

  6. 深度克隆(对象、数组)--------百度IFE前端task2

    var srcObj = { a: 1, b: { b1: ["hello", "hi"], b2: "JavaScript" }}; co ...

  7. 在JAVASCRIPT中构建一个复杂的对象,并用JSON进行转换

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 精通C#(第6版)

    <精通C#(第6版)> 基本信息 原书名:Pro C# 5.0 and the .NET 4.5 framework,sixth edition 作者: (美)Andrew Troelse ...

  9. .NET 接口

    接口      接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...

随机推荐

  1. VC判断当前用户有无Administrator的权限(用EqualSid API函数判断与Admin是否在一个组的Sid)

    /************************************************************************/ /* 函数说明:判断有无Administrator ...

  2. 【Xamarin开发 Android 系列 13】 应用打包部署

    原文:[Xamarin开发 Android 系列 13] 应用打包部署 开始倒叙咯................ 先更新大宝部署吧,这个章节比较的Easy,童鞋们不用费脑筋.点解?从界面上填写几个参 ...

  3. POJ_3685_Matrix_(二分,查找第k大的值)

    描述 http://poj.org/problem?id=3685 一个n*n的矩阵,(i,j)的值为i*i+100000*i+j*j-100000*j+i*j,求第m小的值. Matrix Time ...

  4. BZOJ2802: [Poi2012]Warehouse Store

    2802: [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 121  ...

  5. 第一章 用three.js创建你的第一个3D场景

    第一章 用three.js创建你的第一个3D场景 到官网下载three.js的源码和示例. 创建HTML框架界面 第一个示例的代码如下: 01-basic-skeleton.html 位于 Learn ...

  6. Java---XML的解析(1)-DOM解析

    本章只讲DOM解析.接下来还会学习Dom4j和StAX 解析技术 DOM解析: DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档: <user> <name>Ja ...

  7. HDOJ/HDU 1022 Train Problem I(模拟栈)

    Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot o ...

  8. DAL与数据库类型的对应关系

    MSSQL Server类型 DbType类型 C#类型   MySql类型 DbType类型 C#类型 bit Boolean bool   bit(1) Boolean bool tinyint ...

  9. Qualcomm 8X camera daemon进程浅析

    Camera 先看一下抽象层的主要流程: 首先启动一个守护进程 int qcamsvr_start(void)( qcamsvr.c) { 1. server_fd = open(server_dev ...

  10. MyEclipe 配置 ivy 插件

    在 MyEclipse 装插件绝对不是技术的问题.只要你有足够的耐心和时间. 经过两次试验,在 MyEclipse 配置插件大概流程如下. 配置ivy:   1.打开配置中心     2.选择[Sof ...