最近做项目中,有一个场景需要复制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
复制代码 连带着以前的一起改了,这可不是我们想要的效果。以是这种复制算浅克隆。
怎样连元素一起复制(深克隆)
- 手动复制,foreach 循环 new对象手动插入新的list
- 第三方工具 automapper等
- 序列化和反序列化,通过将对象序列化为一个字节省,然后再反序列化回来,可以实现深克隆
- 表达式树大概反射,代码如下
- 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();
- }
复制代码 总结
以前由于经常做雷同的,明白照旧很清楚,好久不做到了现在一下就踩坑了,以是为了以后不继承踩坑,决定记录下来。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |