时间:2024-11-05 23:08
人气:
作者:admin
最近做项目中,有一个场景需要复制list给其他对象的属性赋值,然后再去根据对象的其他属性操作list的元素数据,其实就是一个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
连带着以前的一起改了,这可不是我们想要的结果。所以这种复制算浅克隆。
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();
}
以前由于经常做类似的,理解还是很清楚,好久不做到了现在一下就踩坑了,所以为了以后不继续踩坑,决定记录下来。
上一篇:第47篇 简单IOC介绍
下一篇:AOT使用经验总结
如何在 DotNet 中使用类似 golang 的 vendor 的