关于Clone


关于Clone的学习

前阵子看到blog中关于Clone的资料

整理下:
关于浅表CLONE,用一个指针指向该地址。也就是说至少有2个指针指向这个地址。
深度CLONE,就是新建一个,并复制原有的数据。克隆对象和原始对象地址肯定不一样。

本人用以下代码测试:

ContractedBlock.gifExpandedBlockStart.gif1    深度复制(Deep Copy)与浅表复制(Shadow Copy)的比较#region 深度复制(Deep Copy)与浅表复制(Shadow Copy)的比较
InBlock.gif 
2    //深度复制(Deep Copy)与浅表复制(Shadow Copy)的比较
InBlock.gif
 3    public class Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
4    dot.gif{
InBlock.gif 
5        public string FirstName;
InBlock.gif 
6        public string LastName;
ExpandedSubBlockEnd.gif 
7    }

InBlock.gif 
8    public class Person:ICloneable
ExpandedSubBlockStart.gifContractedSubBlock.gif 
9    dot.gif{
InBlock.gif
10        public Name PersonName;
InBlock.gif
11        public string Email;
ExpandedSubBlockStart.gifContractedSubBlock.gif
12        /**//// <summary>
ExpandedSubBlockStart.gifContractedSubBlock.gif13        /**//// Deep Copy的例子
ExpandedSubBlockStart.gifContractedSubBlock.gif14        /**//// </summary>
ExpandedSubBlockStart.gifContractedSubBlock.gif15        /**//// <returns></returns>
InBlock.gif16        public Object Clone()
ExpandedSubBlockStart.gifContractedSubBlock.gif
17        dot.gif{
InBlock.gif
18            Person p = new Person();
InBlock.gif
19            p.Email = this.Email;
InBlock.gif
20            p.PersonName = new Name();
InBlock.gif
21            p.PersonName.FirstName = this.PersonName.FirstName;
InBlock.gif
22            p.PersonName.LastName = this.PersonName.LastName;
InBlock.gif
23            return p;
ExpandedSubBlockEnd.gif
24        }

InBlock.gif
25
InBlock.gif
26        public Person ReturnOne()
ExpandedSubBlockStart.gifContractedSubBlock.gif
27        dot.gif{
InBlock.gif
28            return this.MemberwiseClone() as Person;
ExpandedSubBlockEnd.gif
29        }

InBlock.gif
30
InBlock.gif
31        public void ChangLastName(string lastName)
ExpandedSubBlockStart.gifContractedSubBlock.gif
32        dot.gif{
InBlock.gif
33            this.PersonName.LastName = lastName;
ExpandedSubBlockEnd.gif
34        }

ExpandedSubBlockEnd.gif
35    }

ExpandedBlockEnd.gif
36    #endregion

None.gif
37
None.gif
38    //测试点:
None.gif
39    private void button2_Click(object sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
40    dot.gif{
InBlock.gif
41        Person p = new Person();
InBlock.gif
42        p.PersonName = new Name();
InBlock.gif
43        p.PersonName.LastName = "jill";
InBlock.gif
44        p.PersonName.FirstName = "zhang";
InBlock.gif
45        p.Email = "jillzhang@126.com";
InBlock.gif
46        Person sameNamePerson = p.Clone() as Person;
InBlock.gif
47        sameNamePerson.ChangLastName("clr_");
InBlock.gif
48        this.TestInfo.Text += "深度克隆原始数据:" + p.PersonName.LastName + "\r\n";
InBlock.gif
49        this.TestInfo.Text += "深度克隆数据:" + sameNamePerson.PersonName.LastName + "\r\n";            
InBlock.gif
50          
InBlock.gif
51        this.TestInfo.Text += "浅表克隆原始数据:" + p.PersonName.LastName + "\r\n";
InBlock.gif
52        Person samePerson = p.ReturnOne();
InBlock.gif
53        samePerson.ChangLastName("Shadow");
InBlock.gif
54
InBlock.gif
55            
InBlock.gif
56        this.TestInfo.Text += "浅表克隆数据:" + samePerson.PersonName.LastName + "\r\n";            
InBlock.gif
57        this.TestInfo.Text += "深度克隆数据:" + sameNamePerson.PersonName.LastName + "\r\n";               
ExpandedBlockEnd.gif
58    }

None.gif


显示结果:
深度克隆原始数据:jill
深度克隆数据:clr_
浅表克隆原始数据:jill
浅表克隆数据:Shadow
深度克隆数据:clr_

特别说明的是:
DataSet

DataSet有个Clone和继承ICloneable后调用MemberwiseClone结果不一样,至于Copy属于浅表克隆还是深度克隆,暂时观察到结果。

还是先看下代码吧:

 1None.gifprivate void button3_Click(object sender, System.EventArgs e)
 2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 3InBlock.gif    DataSet first = new DataSet();
 4InBlock.gif    DataTable table = first.Tables.Add("table");
 5InBlock.gif    table.Columns.Add("C1"typeof(int));
 6InBlock.gif    table.Columns.Add("C2"typeof(char));
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    table.PrimaryKey = new DataColumn[] dot.gif{ table.Columns[0] };
 8InBlock.gif    for (int i = 0; i < 26++i)
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
10ExpandedSubBlockStart.gifContractedSubBlock.gif        table.Rows.Add(new object[] dot.gif{ i, (char)((ushort)'a' + i) });
11ExpandedSubBlockEnd.gif    }

12InBlock.gif
13InBlock.gif    DataSet clone = first.Clone();
14InBlock.gif
15InBlock.gif    DataSet copy = first.Copy();   
16InBlock.gif        
17InBlock.gif    first.Dispose();
18InBlock.gif
19InBlock.gif    if (first == null)
20InBlock.gif        this.TestInfo.Text += "first has disponsed! \r\n";
21InBlock.gif
22InBlock.gif    this.TestInfo.Text += "Clone 结构,包括几张表:" + clone.Tables.Count.ToString() + "\r\n";
23InBlock.gif    if (clone.Tables.Count > 0)
24ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
25InBlock.gif        this.TestInfo.Text += "表列还在么?" + clone.Tables[0].Columns.Count.ToString() + "\r\n";
26InBlock.gif        this.TestInfo.Text += "表数据还在么?行数:" + clone.Tables[0].Rows.Count.ToString() + "----我clone本身就没有数据\r\n";
27ExpandedSubBlockEnd.gif    }

28InBlock.gif
29InBlock.gif    this.TestInfo.Text += "Copy 结构,包括几张表:" + copy.Tables.Count.ToString() + "\r\n";
30InBlock.gif    if (clone.Tables.Count > 0)
31ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
32InBlock.gif        this.TestInfo.Text += "表列还在么?列数:" + copy.Tables[0].Columns.Count.ToString() + "\r\n";
33InBlock.gif        this.TestInfo.Text += "表数据还在么?行数:" + copy.Tables[0].Rows.Count.ToString() + "\r\n";
34ExpandedSubBlockEnd.gif    }

35InBlock.gif
36ExpandedBlockEnd.gif}

37None.gif
38None.gif

测试结果:
Clone 结构,包括几张表:1
表列还在么?2
表数据还在么?行数:0----我clone本身就没有数据
Copy 结构,包括几张表:1
表列还在么?列数:2
表数据还在么?行数:26


为了让浏览者理解原始的,我拷贝了MSDN的部分资料:
[Begin]
.NET on Clonation
You find two kinds of types in .NET: value and reference. The former includes primitive types, enums and structs, and is allocated on the stack. The latter includes classes and arrays and goes to the heap. Basically, a value type carries all of its content with it. By contrast, a reference type points to a memory buffer where all, or part, of its content is maintained.

In .NET you can duplicate objects in two ways that offer different functionality and power. You can create either a shallow or deep copy of a .NET object.

A shallow copy is a copy of the object only. If the object has a complex structure and contains references to child objects, these won't be duplicated. Any of these child objects will refer to the original object in the shallow copy. (More or less what happens with the data, but not with bookmarks and filters, in a cloned ADO Recordsets.)

A deep copy is a full copy of the object. You get a new object in which everything that is directly or indirectly referenced by the original object is duplicated.

The root object of the .NET Framework, namely the Object object, has a method called MemberwiseClone that creates a shallow copy of the current object.

protected object MemberwiseClone();

This method represents the built-in capability of .NET objects to implement shallow copy. The method is protected and cannot be overridden.

If you think that the standard shallow copy mechanism doesn't work for your objects, you either provide a brand new method to clone/copy them or you implement the ICloneable interface. If you want more than the standard clonation—a shallow copy as described earlier—some measure must be taken.

[End]








转载于:https://www.cnblogs.com/GoGoagg/archive/2008/07/16/1244308.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值