谈C#对象复制

再谈C#对象复制        

对象复制的种类: 1.C# 不提供复制构造函数。如果您创建了新的对象并希望从现有对象复制值,您必须自行编写适当的方法。
示例
在本示例中, 2. ICloneable接口来对对象进行克隆。当然,你也可以不去实现 ICloneable接口。
<span style="line-height: 19px; font-family:;" "="" times="" new="" roman';="">       具体实现方法:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CloneSample
{
        [Serializable]
         class CloneClass : ICloneable
        {
                 int num;         //值类型

                 public int Num //封装值字段
                {
                        get { return num; }
                        set { num = value; }
                }
                 string str;     //string引用类型

                 public string Str //封装引用字段
                {
                        get { return str; }
                        set { str = value; }
                }
                 //数组引用类型
                 public int[] intArr = new int[2];

                 //实现接口的方法
                 public Object Clone()
                {
                         //return this;                                        //返回同一个对象的引用
                             //return this.MemberwiseClone();    //返回一个浅表副本
                             //return new CloneClass();                //返回一个深层副本
                        {                                                                 //返回一个内存副本
                                MemoryStream stream = new MemoryStream();
                                BinaryFormatter formatter = new BinaryFormatter();
                                formatter.Serialize(stream, this);
                                stream.Position = 0;
                                 
                                 return formatter.Deserialize(stream);
                                

                        }

                }
        }
         //执行类
         class ProgramRun
        {
                 public static void Main()
                {
                        CloneClass cs = new CloneClass();
                         //第一次给对象赋值
                       cs.Num = 1;
                        cs.Str = "A";
                        cs.intArr[0] = 100;
                        CloneClass cs1 = cs.Clone() as CloneClass;
                        Console.WriteLine( "**************初始化*****************");
                        Console.WriteLine( "cs对象的值类型:{0}", cs.Num);
                        Console.WriteLine( "cs对象的string引用类型:{0}", cs.Str);
                        Console.WriteLine( "cs对象的数组类型:{0}", cs.intArr[0]);
                        Console.WriteLine( "-------------------------------------------------");
                        Console.WriteLine( "cs1对象的值类型:{0}", cs1.Num);
                        Console.WriteLine( "cs1对象的string引用类型:{0}", cs1.Str);
                        Console.WriteLine( "cs1对象的数组类型:{0}", cs1.intArr[0]);
                         //第二次给原始对象复制
                        cs.Num = 2;
                        cs.Str = "B";
                        cs.intArr[0] = 200;
                         //现在我们看看cs和cs1两个对象的值
                        Console.WriteLine( "**************先将cs值改变后变化如下*****************");
                        Console.WriteLine( "cs对象的值类型:{0}", cs.Num);
                       Console.WriteLine( "cs对象的string引用类型:{0}", cs.Str);
                        Console.WriteLine( "cs对象的数组类型:{0}", cs.intArr[0]);
                        Console.WriteLine( "-------------------------------------------------" );
                        Console.WriteLine( "cs1对象的值类型:{0}", cs1.Num);
                        Console.WriteLine( "cs1对象的string引用类型:{0}", cs1.Str);
                        Console.WriteLine( "cs1对象的数组类型:{0}", cs1.intArr[0]);
                         //现在我们给副本对象进行赋值看看原始对象的值
                        cs1.Num = 3;
                       cs1.Str = "C";
                        cs1.intArr[0] = 300;
                        Console.WriteLine( "**************先将cs1值改变后变化如下*****************");
                        Console.WriteLine( "cs对象的值类型:{0}", cs.Num);
                        Console.WriteLine( "cs对象的string引用类型:{0}", cs.Str);
                        Console.WriteLine( "cs对象的数组类型:{0}", cs.intArr[0]);
                        Console.WriteLine( "-------------------------------------------------");
                        Console.WriteLine( "cs1对象的值类型:{0}", cs1.Num);
                       Console.WriteLine( "cs1对象的string引用类型:{0}", cs1.Str);
                        Console.WriteLine( "cs1对象的数组类型:{0}", cs1.intArr[0]);
                        Console.WriteLine( "Output Complete!Press Any Key To Continue.");
                        Console.ReadKey();
                }
        }
}
输出结果分析:
1. 返回同一个对象的引用的结果:
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
cs1对象的值类型:2
cs1对象的string引用类型:B
cs对象的数组类型:200
cs对象的值类型:3
cs对象的string引用类型:C
cs对象的数组类型:300
可以看到,cs和cs1完全是同一个对象,cs修改,cs1的值也跟着改变;cs1修改,cs也跟着改变。
2.返回一个浅表副本的结果:
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
cs1对象的值类型:1
cs1对象的string引用类型:A
cs对象的数组类型:200
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:300
这个结果可以看出,浅表副本和原始副本并不是一个对象,但是,浅表副本复制了原始对象的值类型和string类型,但是数组只复制了引用。这个现象很有趣,按照MSDN的定义:“MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。”,但是,在实际上,string应该也是引用类型,但是,浅表副本却复制了这个值。
3 返回一个深层副本的结果
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
cs1对象的值类型:0
cs1对象的string引用类型:
cs对象的数组类型:0
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
从结果可以看到,深层副本完全复制了对象的结构。
4.返回一个内存副本的结果
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
cs1对象的值类型:1
cs1对象的string引用类型:A
cs对象的数组类型:100
cs对象的值类型:2
cs对象的string引用类型:B
cs对象的数组类型:200
从结果看出,内存深层复制完全对原始对象进行了复制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值