C#_深拷贝和浅拷贝

本文详细介绍了深拷贝和浅拷贝的概念,指出深拷贝复制对象包括值类型和引用类型的所有字段的值,而浅拷贝仅复制值类型和引用类型的引用。文中通过Person类的示例展示了深拷贝和浅拷贝的实现,并提供了使用MemberwiseClone方法的浅拷贝示例。此外,还提及了一种通用的序列化深拷贝方法。文章强调了string类型的特殊性,虽然理论上是引用类型,但在实践中表现得像值类型。
摘要由CSDN通过智能技术生成

一、概念

深拷贝:复制对象中所有值类型和引用类型的字段的值,副本是重新创建的一个对象,对象中字段只是复制的所有字段的值,没有复制引用。所以副本对象内的值并不会因为源对象数据的值的修改而改变。

浅拷贝:同样会复制对象中所有值类型,但是引用类型复制的是引用,所以在源对象数据中如果引用类型数据变化了,副本中的数据也会变化。

值的一提的是,string类型理论上是引用类型,但是表现上是值类型,因为字符串类型的唯一性。

二、微软已提供的接口和方法

MemberwiseClone 方法:创建当前 System.Object 的浅表副本(浅拷贝),它是object类型的一个保护类型的方法,只能在其派生类的内部使用。

ICloneable 接口:只包含一个Clone方法。具体实现自定义,但是一般是深拷贝,因为浅拷贝已经提供了一个方法。

三、示例

public class Person : ICloneable
{
    public string Name { get; set; }
    public uint Age { get; set; }

    public byte[] Data { get; set; }

    //DeepCopy
    public object Clone()
    {
        byte[] data = new byte[3];

        this.Data.CopyTo(data, 0);//这里只需要拷贝源对象的数据,不需要拷贝引用
        Person person = new Person
        {
            Name = this.Name,
            Age = this.Age,
            Data = data,//所以不能在这里直接赋值
        };
        return person;
    }

    //ShallowCopy
    public Person ShallowCopy()
    {
        return (Person)this.MemberwiseClone();
    }

    public override string ToString()
    {
        return $"{Name} {Age} {BitConverter.ToString(Data)}";
    }
}

官方链接

另外还有一种通用的深拷贝方式,用到了序列化:

public static T DeepClone<T>(this T obj)
{
 using (var ms = new MemoryStream())
 {
   var formatter = new BinaryFormatter();
   formatter.Serialize(ms, obj);
   ms.Position = 0;

   return (T) formatter.Deserialize(ms);
 }
}

使用的时候需要把T类型加上[Serialize]特性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值