首页 > 其他分享 >list拷贝踩坑记录

list拷贝踩坑记录

时间:2024-11-05 22:58:06浏览次数:1  
标签:Console 记录 list item WriteLine new 拷贝 lista

最近做项目中,有一个场景需要复制list给其他对象的属性赋值,然后再去根据对象的其他属性操作list的元素数据,其实就是一个list的拷贝问题

代码还原

一个list集合,元素类型为class,复制一下list,但是list里面元素还是指向原来的对象

internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
        var lista = new List<People>();
        lista.Add(new People()
        {
            Name = "LaoWang",
            Age= 1
        });
        lista.Add(new People() 
        {
            Name = "LaoLi",
            Age = 2
        });
        lista.Add(new People()
        {
            Name = "LaoZhang",
            Age = 3
        });

        var listb = new List<People>(lista);
        listb.Add(new People()
        {
            Name = "LaoLiu",
            Age = 4
        });

        Console.WriteLine("lista:");
        foreach (var item in lista)
        {
            Console.WriteLine(item.Name);
            Console.WriteLine(item.Age);
        }

        Console.WriteLine(" ");
        Console.WriteLine("listb:");
        foreach (var item in listb)
        {
            Console.WriteLine(item.Name);
            Console.WriteLine(item.Age);
        }

    }
}

public record People
{
    public string Name { get; set; }

    public int Age { get; set; }
}

输出结果:

Hello, World!
lista:
LaoWang
1
LaoLi
2
LaoZhang
3

listb:
LaoWang
1
LaoLi
2
LaoZhang
3
LaoLiu
4

增加了元素,表面上是没有什么影响的,但是如果我修改呢:

foreach (var item in listb)
{
    item.Name = "DDl";
    item.Age = 8;
}

Console.WriteLine("new lista:");
foreach (var item in lista)
{
    Console.WriteLine(item.Name);
    Console.WriteLine(item.Age);
}

Console.WriteLine(" ");
Console.WriteLine("new listb:");
foreach (var item in listb)
{
    Console.WriteLine(item.Name);
    Console.WriteLine(item.Age);
}

结果变成了:

new lista:
DDl 8
DDl 8
DDl 8
new listb:
DDl 8
DDl 8
DDl 8
DDl 8

连带着以前的一起改了,这可不是我们想要的结果。所以这种复制算浅克隆。

如何连元素一起复制(深克隆)

  1. 手动复制,foreach 循环 new对象手动插入新的list
  2. 第三方工具 automapper等
  3. 序列化和反序列化,通过将对象序列化为一个字节流,然后再反序列化回来,可以实现深克隆
  4. 表达式树或者反射,代码如下
public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        formatter.Serialize(ms, obj);
        ms.Seek(0, SeekOrigin.Begin);
        return (T)formatter.Deserialize(ms);
    }
}

public static List<T> DeepCloneList<T>(List<T> list)
{
    return list.Select(item => DeepClone(item)).ToList();
}

总结

以前由于经常做类似的,理解还是很清楚,好久不做到了现在一下就踩坑了,所以为了以后不继续踩坑,决定记录下来。

标签:Console,记录,list,item,WriteLine,new,拷贝,lista
From: https://www.cnblogs.com/guoxiaotian/p/18529053

相关文章

  • 拷贝构造(详解)
    一、拷贝构造函数拷贝构造函数,就像他的名字一样,使来拷贝的,他的作用是把一个已经存在的对象进行拷贝后,用拷贝来的值进行给其他对象赋值和作为返回值和参数等。一、拷贝构造函数调用时机拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化......
  • WPF ListBox MVVM scrollintoview via behavior
    publicclassListBoxAutoScrollBehavior:Behavior<ListBox>{protectedoverridevoidOnAttached(){base.OnAttached();AssociatedObject.SelectionChanged+=AssociatedObject_SelectionChanged;}privatevoidAsso......
  • 记录一次计数代替空延时的按键检测方法ByWYJ
    //按键处理voidkeyProc(void){ staticunsignedintCnt=0,KEY=0; if((GPIO_ReadInputData(GPIOA)&0xF000)!=0xF000)//按下时刻:判断GPIOA口是否有一个或多个按键按下 { Cnt+=1; KEY=GPIO_ReadInputData(GPIOA); if(Menu==5)//当Menu==5且GPIO_......
  • scala学习记录,Set,Map
    set:集合,表示没有重复元素的集合,特点:唯一语法格式:val变量名=Set[类型](元素1,元素2...)可变不可变可变(mutable)可对元素进行添加,删除等操作;不可变(immutable)创建后元素不能修改如果要定义可变的Set(mutable),需要额外导入包:importscala.collection.mutableSet常见操作对于......
  • CentOS7执行yum命令遇到“Could not resolve host: mirrorlist.centos.org; 未知的错误
    LoadingmirrorspeedsfromcachedhostfileCouldnotretrievemirrorlisthttp://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stockerrorwas14:curl#6-"Couldnotresolvehost:mirrorlist.centos.org;未知的错误"Oneo......
  • 劫持微信聊天记录并分析还原 —— 解密数据库(二)
    本工具设计的初衷是用来获取微信账号的相关信息并解析PC版微信的数据库。程序以Python语言开发,可读取、解密、还原微信数据库并帮助用户查看聊天记录,还可以将其聊天记录导出为csv、html等格式用于AI训练,自动回复或备份等等作用。下面我们将深入探讨这个工具的各个方面及其......
  • QueryExecutionListener 实现 SPARK SQL 数据血缘
    背景数据血缘是数据资产管理非常重要的一部份,团队现在已经实现通过Hook上报HiveSQL任务数据血缘,通过impalalineage日志获取impala任务数据血缘。随着SparkSQL计算引擎的使用,现针对该场景设计可行的血缘获取方案。方案思路分析在spark的源码中,以Scala的形式提供了......
  • 【Java】常用类方法记录
    Arrays类java.util.Arrays返回类型方法描述static<T>List<T>asList(T…a)返回由指定数组支持的固定大小的列表。staticintbinarySearch(byte[]a,bytekey)使用二进制搜索算法在指定的字节数组中搜索指定的值。staticintbinarySearch(byte[]a,intfromIndex,in......
  • 每天两个知识点 拷贝构造函数和赋值运算符重载的作用&C++模板及其类型
    1)拷贝构造函数和赋值运算符重载的作用拷贝构造函数(CopyConstructor)和赋值运算符重载(AssignmentOperatorOverload)是C++中处理对象复制和赋值的两个重要机制。拷贝构造函数:拷贝构造函数是一个特殊的构造函数,它用于创建一个新对象,并将其初始化为另一个同类型对象的副本。......
  • 记录一下从keil官网下载DFP(芯片支持包)的方法
    1.打开官网www.keil.arm.com2.点击右上角的下载按钮,进入下一页面3.选择MDK-ARM会进入到MDK下载页面。这里我们不用下载MDK。4.选择左下角的芯片列表按钮5.选择我们使用的芯片(我这里使用的是STM32L051系列)6.然后选择DFP7.在右上角选择下载DFP文件......