java copyto_C#数组中CopyTo()和Clone()的区别(转)

有很多初学者会对CopyTo()和Clone()的区别弄不清楚.在网上搜索一下,大多数解说的程序员都把问题引到浅拷贝和深拷贝的区别上去了,关于浅拷贝和深拷贝确实解释的很清楚,可是这并没有让初学者减轻疑惑.所以特此写点东西,解释下这两个方法的共同点和区别,同时解释下浅拷贝和深拷贝.

相信大多数C#程序员都有查阅MSDN的好习惯,但是MSDN中提到这两个方法最大的区别就是:一个方法创建了一个新Array对象,一个方法只是复制了Array引用.这句话本身没有错误,而且也正是他们的区别所在.只是这样会让人感到很迷惑.到底是什么区别呢?这里还是先说说他们的共同点:CopyTo()和Clone()都属于浅拷贝,这一点是毋庸置疑的.对于浅拷贝:如果数组中的成员为值类型(如:int,float,double,byte等),则完全复制数值到目标数组中,如果是引用类型(如用户自定义类型:class Student,class People,或者是类库中的类类型:ArrayList等),则指复制引用给目标数组.文字有时候不如代码来得容易理解.但是这里也许用图更容易理解,看下图:

假定创建一个学生类数组Student[],然后浅拷贝到另一个学生类数组Student1[]中.

82cc2426a792c140c8471c42041cb2c9.gifcb65acc3013e5aadca7caf76250d05ae.gif

从图中很容易看出所谓的浅拷贝对于引用类型,仅仅只是复制引用.通过一个数组修改内存中的值会影响另一个数组对内存对象的引用.

那么CopyTo()和Clone()方法的区别是什么呢?其实他们的区别,也就是MSDN上说的最大的区别就是用法上的区别.我们可以在VS弹出智能提示的时候看看他们的返回值,CopyTo()的返回值是void,使用方法如下Array1.CopyTo(Array2,0);其中Array2必须是一个已经实例化的数组.而Clone()的返回值是object.使用方法如下Array2 = Array1.Clone();其中Array2不必实例化.这样,我相信理解这两个方法的区别就很容易了.本质上并没有什么区别.都属于浅拷贝.如果拷贝所有的数组,就是用Clone().但是如果只是拷贝一部分,就可以选择CopyTo()了,CopyTo()的参数提示是这样的CopyTo(Array array,int Index).第二个参数index(索引)是指明从数组中的第几个对象开始复制.

相信到这里.应该很容易理解CopyTo()和Clone().下面说说浅拷贝和深拷贝的区别.

如上面所说的,浅拷贝对于值类型则复制值,对于引用类型则复制对象的引用(类似于指针).深拷贝则是完完全全的创建一个个新对象.对原来数组中的所有对象全部创建新对象.对新数组中的修改不会影响原来数组中的值或对象.但是如何实现深拷贝呢?.NET库中似乎没有深拷贝的方法.这和实现深拷贝的原理有关系.若用户希望实现深拷贝.希望出现两个完全一样但又互不影响的数组.则必须自己写方法,对原数组中的每个对象实现拷贝,层层深入,直到这个对象中的对象中的对象……中的对象为值类型为止,因为只有值类型才是完全拷贝,对一个值进行修改不会影响另一个相同的值.这么说又有点难理解了.实现深拷贝的方法,如下图:

图中,蓝色代表值类型,直接copy,而红色代表引用类型,需要层层深入直到最后一层是复制值类型为止(这个图画得欠雅观,不过基本表达了深拷贝的原理).

总结

8aad3ac6324b14b0733cae3b3bf4e93a.gif

1 都是浅拷贝

2 都是拷贝所有的source到destination

3copyto的destination是实例化的,而clone的destination必须是实例化的。

using System;

public class SamplesArray

{

public static void Main()

{

// Creates and initializes two new Arrays.

Array mySourceArray = Array.CreateInstance(typeof(String), 6);

mySourceArray.SetValue("three", 0);

mySourceArray.SetValue("napping", 1);

mySourceArray.SetValue("cats", 2);

mySourceArray.SetValue("in", 3);

mySourceArray.SetValue("the", 4);

mySourceArray.SetValue("barn", 5);

Array myTargetArray;

//Array myTargetArray = Array.CreateInstance(typeof(String), 15);

//myTargetArray.SetValue("The", 0);

//myTargetArray.SetValue("quick", 1);

//myTargetArray.SetValue("brown", 2);

//myTargetArray.SetValue("fox", 3);

//myTargetArray.SetValue("jumps", 4);

//myTargetArray.SetValue("over", 5);

//myTargetArray.SetValue("the", 6);

//myTargetArray.SetValue("lazy", 7);

//myTargetArray.SetValue("dog", 8);

// Displays the values of the Array.

//Console.WriteLine("The target Array contains the following (before and after copying):");

//PrintValues(myTargetArray, ' ');

// Copies the source Array to the target Array, starting at index 6.

//mySourceArray.CopyTo(myTargetArray, 6); //这里是编译不过去的,因为CopyTo要求destination必须实例化

myTargetArray = (string[])mySourceArray.Clone(); //没有问题,因为Clone不要求destination必须实例化

// Displays the values of the Array.

PrintValues(myTargetArray, ' ');

Console.ReadLine();

}

public static void PrintValues(Array myArr, char mySeparator)

{

System.Collections.IEnumerator myEnumerator = myArr.GetEnumerator();

int i = 0;

int cols = myArr.GetLength(myArr.Rank - 1);

while (myEnumerator.MoveNext())

{

if (i < cols)

{

i++;

}

else

{

Console.WriteLine();

i = 1;

}

Console.Write("{0}{1}", mySeparator, myEnumerator.Current);

}

Console.WriteLine();

}

}

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2010-04-28 10:24

浏览 1450

评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值