zoukankan      html  css  js  c++  java
  • 浅拷贝和深拷贝

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

      (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;//深拷贝

    五、深拷贝方法

      实现深拷贝的方式有:反射、反序列化。反射容易引起相互引用的问题,要注意;反序列化的方式也可以细分为3种,利用二进制序列化和反序列实现、利用XML序列化和反序列化实现、利用DeserializeObject

      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;
        }
  • 相关阅读:
    数据库性能测试---前阿里数据库团队资深DBA杨奇龙
    阿里云 MYSQL 与 PG(丁奇与德哥)
    RHEL6中ulimit的nproc限制
    Linux下文件描述符
    Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列
    5.6 太多分区引起OOM
    Linux lsof命令使用小结
    重现PHP Core的调用栈
    用GDB排查Python程序故障
    mysql 索引优化
  • 原文地址:https://www.cnblogs.com/qtiger/p/13087921.html
Copyright © 2011-2022 走看看