c#深度复制 浅度复制

c#中没有指针的概念。但并不代表c#中没有引用的地址。相反,可能很多人会忽略这点。如果不遇到问题,我可能会一直在这个地方模模糊糊吧。

举个实际碰到的例子。

有一个类。实例化复制后想保留这个实例的一个备份。

例如 

//Clone类中包含一个int length字段。
Clone cloneTest=new Clone();
Clone cloneCopy=new Clone();
cloneTest..length=0;
cloneCopy=cloneTest;

到这个部分都是正常的,实际上cloneTest和cloneCopy中的length值都变为0了。 但如果接着加一行代码

cloneTest.length=1;

预期是希望cloneTest中length=1而cloneCopy中length=0;但实际两者都变为1了。

指针没学好。没想到c#没指针但是却包含了指针的作用。

这里出现这个原因就是因为类是个引用类型,所以当执行

cloneCopy=cloneTest;时,是将地址给过去了。于是当然一者变。两者都会变了。

c#中的引用类型采用这种方法都是给地址。复制引用地址就是浅度复制。而复制对象的值,创建新的对象就是深度复制。

于是现在的问题就要记住哪些为引用类型,哪些为值类型了。(我一直觉得记着没用,懒得记。但这个一定得记住)

以下不全,只记录了我用到过的。

引用类型:

字符串:string型 最常见的引用类型,他被定义成引用类型的意义我不知道。但这里要强调的是,它被重写了Equal方法。使用方法与值类型类似。(实际上给string赋新值是重新给赋了一个新的地址)所以在大部分情况下就把他当成值类型没啥问题。

 

数组

接口

 

值类型:

结构体

数值类型

枚举类型

bool类型

 

这样,深度复制和浅度复制的意义就产生了。我想备份一个实例化后的类的数据。结果它会跟着变化,这是很郁闷的事情。这种情况就要进行深度复制。

深度复制方法很多。这是我在网上找的一个方法,特别简单。原理也很清晰。

 

以下为转载

为了实现深度复制,我们就必须遍历有相互引用的对象构成的图,并需要处理其中的循环引用结构。这无疑是十分复杂的。幸好借助.Net的序列化和反序列化机制,可以十分简单的深度Clone一个对象。原理很简单,首先将对象序列化到内存流中,此时对象和对象引用的所用对象的状态都被保存到内存中。.Net的序列化机制会自动处理循环引用的情况。然后将内存流中的状态信息反序列化到一个新的对象中。这样一个对象的深度复制就完成了。

深度复制帮助类,验证过,这个类是可用的。使用的时候只需建个内部类即可


public static class ObjectCopier
{
    /// <summary>
    /// Perform a deep Copy of the object.
    /// </summary>
    /// <typeparam name="T">The type of object being copied.</typeparam>
    /// <param name="source">The object instance to copy.</param>
    /// <returns>The copied object.</returns>
    public static T Clone<T>(T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }

        // Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值