C# 对象拷贝

深拷贝

  1. 利用 Newtonsoft.Json 序列化
/*
利用 json 进行深拷贝
*/
using System;
using Newtonsoft.Json;

namespace Copy
{
    class Program
    {
        static void Main(string[] args)
        {
            
            var obj = new Model();
            obj.a = "1";
            obj.b = "2";
            var strObj  = JsonConvert.SerializeObject(obj);
            var newObj = JsonConvert.DeserializeObject<Model>(strObj);
            newObj.a = "3";
            newObj.b = "4";
            Console.ReadKey();
        }
    }
}

  1. XML 序列化
		/// <summary>
        /// xml序列化的方式实现深拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T XmlDeepCopy<T>(T t)
        {
            //创建Xml序列化对象
            XmlSerializer xml = new XmlSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream())//创建内存流
            {
                //将对象序列化到内存中
                xml.Serialize(ms, t);
                ms.Position = default;//将内存流的位置设为0
                return (T)xml.Deserialize(ms);//继续反序列化
            }
        }
  1. 内存序列化
        /// <summary>
        /// 二进制序列化的方式进行深拷贝
        /// 确保需要拷贝的类里的所有成员已经标记为 [Serializable] 如果没有加该特性特报错
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T BinaryDeepCopy<T>(T t)
        {
            //创建二进制序列化对象
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())//创建内存流
            {
                //将对象序列化到内存中
                bf.Serialize(ms, t);
                ms.Position = default;//将内存流的位置设为0
                return (T)bf.Deserialize(ms);//继续反序列化
            }
        }
        // 同上方法
		public static T DeepCopy<T>(T obj)
		{
		  object retval;
		  using (MemoryStream ms = new MemoryStream())
		  {
		    BinaryFormatter bf = new BinaryFormatter();
		    //序列化成流
		    bf.Serialize(ms, obj);
		    ms.Seek(0, SeekOrigin.Begin);
		    //反序列化成对象
		    retval = bf.Deserialize(ms);
		    ms.Close();
		  }
		  return (T)retval;
		}
  1. Reflection
public static void CopyValue(object origin,object target)
  {
   System.Reflection.PropertyInfo[] properties = (target.GetType()).GetProperties();
   System.Reflection.FieldInfo[] fields = (origin.GetType()).GetFields();
   for ( int i=0; i< fields.Length; i++)
   {
    for ( int j=0; j< properties.Length; j++)
    {
     if (fields[i].Name == properties[j].Name && properties[j].CanWrite)
     {
      properties[j].SetValue(target,fields[i].GetValue(origin),null);
     }
    }
   }
  }

浅拷贝

  1. MemberwiseClone
using System;

public class IdInfo
{
    public int IdNumber;
    
    public IdInfo(int IdNumber)
    {
        this.IdNumber = IdNumber;
    }
}

public class Person 
{
    public int Age;
    public string Name;
    public IdInfo IdInfo;

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

    public Person DeepCopy()
    {
       Person other = (Person) this.MemberwiseClone();
       other.IdInfo = new IdInfo(IdInfo.IdNumber);
       other.Name = String.Copy(Name);
       return other;
    }
}

public class Example
{
    public static void Main()
    {
        // Create an instance of Person and assign values to its fields.
        Person p1 = new Person();
        p1.Age = 42;
        p1.Name = "Sam";
        p1.IdInfo = new IdInfo(6565);

        // Perform a shallow copy of p1 and assign it to p2.
        Person p2 = p1.ShallowCopy();

        // Display values of p1, p2
        Console.WriteLine("Original values of p1 and p2:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);
        
        // Change the value of p1 properties and display the values of p1 and p2.
        p1.Age = 32;
        p1.Name = "Frank";
        p1.IdInfo.IdNumber = 7878;
        Console.WriteLine("\nValues of p1 and p2 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);

        // Make a deep copy of p1 and assign it to p3.
        Person p3 = p1.DeepCopy();
        // Change the members of the p1 class to new values to show the deep copy.
        p1.Name = "George";
        p1.Age = 39;
        p1.IdInfo.IdNumber = 8641;
        Console.WriteLine("\nValues of p1 and p3 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p3 instance values:");
        DisplayValues(p3);
    }

    public static void DisplayValues(Person p)
    {
        Console.WriteLine("      Name: {0:s}, Age: {1:d}", p.Name, p.Age);
        Console.WriteLine("      Value: {0:d}", p.IdInfo.IdNumber);
    }
}
// The example displays the following output:
//       Original values of p1 and p2:
//          p1 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//       
//       Values of p1 and p2 after changes to p1:
//          p1 instance values:
//             Name: Frank, Age: 32
//             Value: 7878
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 7878
//       
//       Values of p1 and p3 after changes to p1:
//          p1 instance values:
//             Name: George, Age: 39
//             Value: 8641
//          p3 instance values:
//             Name: Frank, Age: 32
//             Value: 7878

参考
https://www.cnblogs.com/heheblog/archive/2018/07/16/net_study_20180716.html
https://www.cnblogs.com/lijIT/p/4572059.html
https://docs.microsoft.com/zh-cn/dotnet/api/system.object.memberwiseclone?view=netframework-4.8#System_Object_MemberwiseClone

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值