【C#】深拷贝和浅拷贝

发布时间:2023年12月27日

深拷贝和浅拷贝的定义

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在复制对象时涉及的两个不同概念

深拷贝(Deep Copy)

  • 定义: 深拷贝是一种复制对象的方法,它创建了一个新对象,并递归地复制原始对象及其所有嵌套的引用类型成员。这意味着在新对象中创建了原始对象及其所有相关对象的独立副本。
  • 特点: 修改一个对象的属性或其中的引用对象不会影响另一个对象。深拷贝通常需要考虑对象图中所有引用类型的复制。

在C#中,实现对象的完全拷贝可以通过实现ICloneable接口使用序列化和反序列化的方法来完成

实现ICloneable接口,需要自己实现Clone方法返回一个深拷贝对象,这边不做赘述。

下面使用通过将对象序列化到内存流,然后再反序列化为新的对象这种方式实现深拷贝。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace frameWorkTest1.utils
{
    /// <summary>
    /// 深拷贝扩展方法
    /// </summary>
    public static class DeepCopyExtensions
    {
        public static T DeepCopy<T>(this T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("The type must be serializable.", nameof(source));
            }

            // Perform deep copy using serialization
            using (MemoryStream memoryStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(memoryStream, source);
                memoryStream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(memoryStream);
            }
        }
    }
}

这边举个例子 User类的 有个类型为B的属性GetB

[Serializable]
    public class User
    {

		private string _userName;

		public string UserName
		{
			get { return _userName; }
			set { _userName = value; }
		}

		private int _age;

		public int Age
		{
			get { return _age; }
			set { _age = value; }
		}


		private B _b;

		public B GetB
		{
			get { return _b; }
			set { _b = value; }
		}


		/// <summary>
		/// 浅拷贝
		/// </summary>
		/// <returns></returns>
		public User ShallowCopy()
		{
            // 浅拷贝,使用Object受保护方法MemberwiseClone
            return (User) this.MemberwiseClone();
		}
		
		/// <summary>
		/// 深拷贝
		/// </summary>
		/// <returns></returns>
		public User DeepCopyS()
		{
			// 调用扩展方法进行深拷贝
			return this.DeepCopy();
		}

    }

	[Serializable]
	public class B
	{
		private int _Num;

		public int Num
		{
			get { return _Num; }
			set { _Num = value; }
		}

	}

使用深拷贝

User user = new User() { 
                UserName = "小米",Age = 18,GetB = new B { Num = 255}
};
// 深拷贝
User user1 = user.DeepCopyS();
user1.GetB.Num = 188;
Console.WriteLine($"user:{user.GetB.Num},user1:{user1.GetB.Num}");

在这里插入图片描述

浅拷贝(Shallow Copy)

  • 定义: 浅拷贝是一种复制对象的方法,它创建了一个新对象,并复制原始对象及其所有值类型成员和引用类型成员的引用(而不是实际的对象)。这意味着新对象中的引用类型成员仍然指向与原始对象相同的对象。
  • 特点: 修改一个对象的属性或其中的引用对象可能会影响另一个对象,因为它们引用相同的对象实例。

总体而言,深拷贝创建了原始对象及其嵌套对象的独立副本,而浅拷贝创建了原始对象及其嵌套对象的引用副本。选择使用深拷贝还是浅拷贝取决于你的需求和数据结构的复杂性。在处理嵌套引用类型时,深拷贝通常更安全,但也可能更耗费资源。

在C#中浅拷贝可以直接使用Object受保护方法MemberwiseClone

参考上述深拷贝中的代码

public User ShallowCopy()
{
          // 浅拷贝,使用Object受保护方法MemberwiseClone
          return (User) this.MemberwiseClone();
}
User user2 = user.ShallowCopy();
user2.GetB.Num = 100;
Console.WriteLine($"user:{user.GetB.Num},user2:{user2.GetB.Num}");

在这里插入图片描述

文章来源:https://blog.csdn.net/xiuyuandashen/article/details/135236137
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。