首页 > 编程语言 >在C#中如何实现集合的深拷贝

在C#中如何实现集合的深拷贝

时间:2024-12-22 09:27:25浏览次数:11  
标签:Name C# MyComplexObject var 集合 new 拷贝 public

在C#中,实现集合的深拷贝(deep copy)涉及创建一个新的集合,并递归地复制原始集合中的所有元素及其嵌套的对象。深拷贝与浅拷贝(shallow copy)的区别在于,深拷贝不仅复制对象的引用,还复制对象本身及其包含的所有子对象。

以下是一些常见集合类型(如List、Dictionary等)的深拷贝实现方法:

1. 使用序列化/反序列化

一种简单且通用的方法是使用序列化(Serialization)和反序列化(Deserialization)。这种方法适用于许多不同类型的对象,包括集合。

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

[Serializable]
public class MyComplexObject
{
    public int Id { get; set; }
    public string Name { get; set; }
    // 其他属性
}

public static class DeepCopier
{
    public static T DeepCopy<T>(T obj)
    {
        using (var ms = new MemoryStream())
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(ms);
        }
    }
}

class Program
{
    static void Main()
    {
        var originalList = new List<MyComplexObject>
        {
            new MyComplexObject { Id = 1, Name = "Object1" },
            new MyComplexObject { Id = 2, Name = "Object2" }
        };

        var copiedList = DeepCopier.DeepCopy(originalList);

        // 修改副本不会影响原始列表
        copiedList[0].Name = "ModifiedCopy";
        Console.WriteLine(originalList[0].Name);  // 输出: Object1
    }
}

2. 手动实现深拷贝

对于简单的集合,可以手动实现深拷贝。这通常涉及递归地复制集合中的每个对象。

using System;
using System.Collections.Generic;
using System.Linq;

public class MyComplexObject
{
    public int Id { get; set; }
    public string Name { get; set; }

    // 假设有一个拷贝构造函数
    public MyComplexObject(MyComplexObject other)
    {
        Id = other.Id;
        Name = other.Name;
        // 如果有其他复杂属性,也需要拷贝
    }
}

public static class DeepCopier
{
    public static List<T> DeepCopyList<T>(List<T> list) where T : new()
    {
        if (list == null) return null;

        var newList = new List<T>();
        foreach (var item in list)
        {
            if (item is MyComplexObject complexItem)
            {
                newList.Add(new MyComplexObject(complexItem)); // 使用拷贝构造函数
            }
            else if (item is IEnumerable<T> enumerableItem)
            {
                newList.Add((T)DeepCopyList((List<T>)enumerableItem)); // 递归拷贝
            }
            else
            {
                newList.Add((T)item.MemberwiseClone()); // 值类型直接浅拷贝
            }
        }
        return newList;
    }
}

class Program
{
    static void Main()
    {
        var originalList = new List<MyComplexObject>
        {
            new MyComplexObject { Id = 1, Name = "Object1" },
            new MyComplexObject { Id = 2, Name = "Object2" }
        };

        var copiedList = DeepCopier.DeepCopyList(originalList);

        // 修改副本不会影响原始列表
        copiedList[0].Name = "ModifiedCopy";
        Console.WriteLine(originalList[0].Name);  // 输出: Object1
    }
}

3. 使用第三方库

还有一些第三方库(如AutoMapper、ValueInjecter等)可以帮助实现深拷贝。这些库通常提供了更灵活和强大的映射功能。

例如,使用AutoMapper:

using AutoMapper;

public class MyComplexObjectProfile : Profile
{
    public MyComplexObjectProfile()
    {
        CreateMap<MyComplexObject, MyComplexObject>();
    }
}

class Program
{
    static void Main()
    {
        var config = new MapperConfiguration(cfg => cfg.AddProfile<MyComplexObjectProfile>());
        var mapper = config.CreateMapper();

        var originalList = new List<MyComplexObject>
        {
            new MyComplexObject { Id = 1, Name = "Object1" },
            new MyComplexObject { Id = 2, Name = "Object2" }
        };

        var copiedList = mapper.Map<List<MyComplexObject>>(originalList);

        // 修改副本不会影响原始列表
        copiedList[0].Name = "ModifiedCopy";
        Console.WriteLine(originalList[0].Name);  // 输出: Object1
    }
}

注意:AutoMapper主要用于对象到对象的映射,对于集合的深拷贝,需要额外配置。

序列化方法简单通用,但性能可能较低;手动实现方法灵活,但需要更多的代码;第三方库提供了灵活性和易用性,但需要额外的依赖。

标签:Name,C#,MyComplexObject,var,集合,new,拷贝,public
From: https://blog.csdn.net/x1234w4321/article/details/144063953

相关文章

  • 使用纯CSS制作一个右上角倾斜四十五度封页角效果
    要使用纯CSS制作一个右上角倾斜45度的封页角效果,你可以使用伪元素(:before或:after)与CSS的transform属性。以下是一个简单的示例,说明如何为页面或元素添加这种效果:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"conte......
  • 使用canvas制作一个圆形进度条
    制作一个圆形进度条使用HTML5的<canvas>元素是一个很好的选择。以下是一个简单的示例,展示了如何使用<canvas>来创建一个圆形进度条:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width......
  • 过滤器Filter vs 拦截器Interceptor
    过滤器FilterJavaWeb三大组件之一,可以把对资源的请求拦截下来,实现一些特殊功能,比如登录校验、统一编码处理、敏感字符处理等拦截器Interceptor概念:一种动态拦截方法调用的机制,类似于Filter,Spring框架提供,用于动态拦截控制器方法的执行作用:拦截请求,在指定的方法调用的前后,根......
  • 纯CSS实现一个梅花图案
    使用纯CSS来创建一个复杂的梅花图案是相当具有挑战性的,因为CSS主要用于描述文档的样式,而不是用于创建复杂的图形。然而,你可以使用CSS的一些特性,如border-radius、transform、box-shadow和伪元素(:before和:after)来尝试创建一个简化的梅花图案。以下是一个使用纯CSS创建简化梅花......
  • 使用CSS3模拟太阳、地球、月球旋转的特效
    要使用CSS3模拟太阳、地球和月球的旋转,你可以利用CSS3的动画和转换功能。以下是一个简单的示例,展示了如何使用HTML和CSS来模拟这个系统。HTML<divclass="solar-system"><divclass="sun"></div><divclass="earth-orbit"><divclass="earth&quo......
  • 使用CSS3制作立体式3D旋转的动画效果
    要使用CSS3制作立体式3D旋转的动画效果,你可以使用CSS3的3D转换(transforms)和动画(animations)特性。以下是一个简单的示例,展示如何创建一个围绕Y轴旋转的3D立方体动画:<!DOCTYPEhtml><html><head><style>.scene{width:200px;height:20......
  • 使用纯CSS3实现大象走路的动画
    创建一个完整的大象走路动画仅使用CSS3是一个相当复杂的任务,因为它涉及到多个部分的动画,如大象的四肢、身体、头部等。以下是一个简化的示例,说明如何使用CSS3的@keyframes和animation属性来制作一个大象走路的基本动画。首先,我们需要定义大象的基本HTML结构:<divclass="elephant......
  • 使用Canvas制作一个火焰跟随鼠标的动画
    创建一个火焰跟随鼠标的动画涉及到多个步骤,包括创建canvas元素,监听鼠标事件,以及在canvas上绘制火焰。以下是一个基本的实现方式:首先,在HTML中添加一个canvas元素:<!DOCTYPEhtml><html><head><title>火焰跟随鼠标动画</title><style>body{margin:0;}......
  • CSS的auto是什么意思?
    在CSS(层叠样式表)中,auto是一个特殊的值,它通常用于让浏览器自动计算某个属性的值。auto的具体行为取决于它应用于哪个属性。以下是一些常见用法:margin:auto;:当用于水平方向的外边距(如margin-left或margin-right)时,auto通常用于水平居中一个块级元素。例如,一个具有width:......
  • 使用Canvas画出头发飘逸的动画
    创建一个头发飘逸的动画需要一定的设计能力和动画技巧。下面我会给出一个简单的步骤来在HTML5的<canvas>元素上创建一个飘逸的头发的动画。步骤1:设置HTML和Canvas首先,你需要在HTML中创建一个<canvas>元素。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-......