zoukankan      html  css  js  c++  java
  • c# 引用类型对象的深拷贝

    c#中的对象大体分为值类型和引用类型,值类型大致包括 int, struct等,引用类型大致包括 自定义Class,object 等。string属于特殊的引用类型,不在本文的讨论之内。

    值类型直接存储对象,而引用类型存储对象的地址,在对引用类型进行复制的时候,也只是复制对象的地址。

    完全复制一个引用类型对象主要有几种方法:

    1.添加一个Copy函数,进行拷贝(如果字段为引用类型,需要循环添加Copy函数,这样情况会变的十分复杂。)

    namespace ConsoleApplication1
    {
        class User
        {
            public string Name { get; set; }
            public string Sex { get; set; }
            public House Home { get; set; }
            public User Copy()
            {
                User newUser = (User)this.MemberwiseClone();
                newUser.Home = this.Home.Copy();
                return newUser;
            }
        }
        class House
        {
            public string Address { get; set; }
            public House Copy()
            {
                return (House)this.MemberwiseClone();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                User a = new User();
                a.Name = "A";
                a.Home = new House() { Address = "长江路" };
                User b = a.Copy();
                b.Name = "B";
                b.Home.Address = "黄河路";
                Console.WriteLine(a.Name);
                Console.WriteLine(a.Home.Address);
                Console.ReadLine();
            }
        }
    }

    2.利用序列化反序列化(对性能会有杀伤)

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                Test t1 = new Test();
                Console.WriteLine(t1.list.Count);
                Test t2 = (Test)Clone(t1);
                t2.list.Add("");
                Console.WriteLine(t2.list.Count);
                Console.WriteLine(t1.list.Count);
                Console.ReadLine();
            }
    
            public static object Clone(object obj)
            {
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                bf.Serialize(ms, obj);
                ms.Position = 0;
                return (bf.Deserialize(ms)); ;
            }
        }
    
        [Serializable]
        public class Test
        {
            public List<string> list = new List<string>();
        }
    }

    3.利用反射(测试了一个网上的接口可用,但是对性能杀伤和序列化反序列化相当,而且可能对代码混淆有一定影响。   https://www.cnblogs.com/zhili/p/DeepCopy.html)

    最后附上微软文档:

    https://docs.microsoft.com/zh-cn/dotnet/api/system.object.memberwiseclone?redirectedfrom=MSDN&view=netframework-4.7.2#System_Object_MemberwiseClone

  • 相关阅读:
    批处理学习笔记9
    批处理学习笔记8
    批处理学习笔记10
    批处理学习笔记7
    批处理学习笔记6
    批处理学习笔记系列
    批处理学习笔记5
    批处理学习笔记3
    批处理学习笔记4
    批处理学习笔记2
  • 原文地址:https://www.cnblogs.com/aitong/p/9437400.html
Copyright © 2011-2022 走看看