浅拷贝和深拷贝

时间:2020-06-10
本文章向大家介绍浅拷贝和深拷贝,主要包括浅拷贝和深拷贝使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、浅拷贝:是指将对象中的所有字段逐字复制到一个新对象

  (1)对值类型字段只是简单的拷贝一个副本到目标对象,改变目标对象中值类型字段的值不会反映到原始对象中,因为拷贝的是副本

  (2)对引用类型字段则是指拷贝他的一个引用到目标对象,改变目标对象中引用类型字段的值会将它反映到原始对象中,因为拷贝的是指向堆是上的一个地址。

二、深拷贝:深拷贝与浅拷贝不同的是对于引用字段的处理,深拷贝会将在新对象中创建一个新的对象和原始对象字段相同的字段,也就是说这个引用和原始对象引用是不同,我们改变新对象这中这个字段的时候是不会影响到原始对象中对应字段的内容。

三、赋值:

  (1)引用类型的赋值就是将原来对象的地址给新的对象拷贝一下即可,新对象的修改会影响原始对象。

  (2)值类型的复制,就是建立副本,副本和原始数据互不干涉

四、浅拷贝方法  

            Animal animal1 = new Animal();

            animal1.Name = "绿狗";

            animal1.Age = 1;

            Animal animal2= animal1;//浅拷贝

            Animal animal3= new Animal();

            animal3.Name = animal1.Name;

            animal3.Age = animal1.Age;//深拷贝

五、深拷贝方法

  1、方式一 使用二进制流

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public static class ObjectCopier
{
    public static T Clone<T>(T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }

        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);
        }
    }
}

  2、使用序列化与反序列化

public static T CloneJson<T>(this T source)
{            
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }

    var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}

  3、使用反射

public static T DeepCopyByReflect<T>(T obj)
{
    //如果是字符串或值类型则直接返回
    if (obj is string || obj.GetType().IsValueType) return obj;
    object retval = Activator.CreateInstance(obj.GetType());
    FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
    foreach (FieldInfo field in fields)
    {
        try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
        catch { }
    }
    return (T)retval;
}

  4、方式四 使用XML序列化与反序列化

  public static T DeserializeXML<T>(string xmlData) where T:new()
    {
        if (string.IsNullOrEmpty(xmlData))
            return default(T);

        TextReader tr = new StringReader(xmlData);
        T DocItms = new T();
        XmlSerializer xms = new XmlSerializer(DocItms.GetType());
        DocItms = (T)xms.Deserialize(tr);

        return DocItms == null ? default(T) : DocItms;
    }

更优秀文章参考:https://www.cnblogs.com/zhili/p/DeepCopy.html

原文地址:https://www.cnblogs.com/qtiger/p/13087921.html