注册
|
登录
发帖
热搜
活动
交友
discuz
论坛
BBS
翼度工具
翼度网址导航
开发工具
Linux命令速查
网页设计配色表
在线制作icon
颜色代码选取器
翼度科技
»
论坛
›
编程开发
›
.net
›
查看内容
返回列表
发新帖
解读 --- 深拷贝
向宝宝的妈
向宝宝的妈
当前离线
积分
15
5
主题
5
帖子
15
积分
新手上路
新手上路, 积分 15, 距离下一级还需 35 积分
新手上路, 积分 15, 距离下一级还需 35 积分
积分
15
发消息
显示全部楼层
引言
深拷贝是指创建一个新对象,该对象的值与原始对象完全相同,但在内存中具有不同的地址。这意味着如果您对原始对象进行更改,则不会影响到复制的对象
常见的C#常见的深拷贝方式有以下4类:
各种形式的序列化及反序列化。
通过反射机制获取该对象的所有字段和属性信息。遍历所有字段和属性,递归将源对象中的值复制到目标对象中。
新建对象,手动复制所有成员变量。
实现 ICloneable 接口,重写 Colne 方法。方法内部可以调用上面任意实现方法。
序列化、反序列化
使用二进制序列化和反序列化
可以使用 BinaryFormatter 类将对象序列化成二进制形式并保存到文件或内存流中,然后再使用 BinaryFormatter 反序列化对象,这样就可以得到该对象的一个完全独立的副本。
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
T copy = (T)formatter.Deserialize(stream);
stream.Close();
return copy;
}
复制代码
使用 XML 序列化和反序列化
可以使用 XmlSerializer 类将对象序列化成 XML 形式并保存到文件或内存流中,然后再使用 XmlSerializer 反序列化对象,这样也可以得到该对象的一个完全独立的副本。
using System.IO;
using System.Xml.Serialization;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
XmlSerializer serializer = new XmlSerializer(typeof(T));
MemoryStream stream = new MemoryStream();
serializer.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
T copy = (T)serializer.Deserialize(stream);
stream.Close();
return copy;
}
复制代码
使用 DataContractSerializer 序列化和反序列化
可以使用 DataContractSerializer 类将对象序列化成 XML 或二进制形式并保存到文件或内存流中,然后再使用 DataContractSerializer 反序列化对象。
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters.Binary;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
T copy = (T)serializer.ReadObject(stream);
stream.Close();
return copy;
}
复制代码
使用 Json.NET 或 System.Text.Json 序列化和反序列化
可以使用 JsonConvert 类将对象序列化成 JSON 字符串,然后再使用 JsonConvert 反序列化对象。
using Newtonsoft.Json;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
string json = JsonConvert.SerializeObject(obj);
T copy = JsonConvert.DeserializeObject<T>(json);
return copy;
}
复制代码
using System.Text.Json;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
string jsonString = JsonSerializer.Serialize<T>(obj);
// 将 JSON 字符串反序列化为对象
var deserializedPerson = JsonSerializer.Deserialize<T>(jsonString);
return deserializedPerson;
}
复制代码
反射
使用反射实现深拷贝
通过反射生成对象,通过反射机制获取该对象的所有字段和属性信息。遍历所有字段和属性,以递归方式将源对象中的值复制到目标对象中。
using System;
using System.Reflection;
public static T DeepCopy<T>(T obj)
{
if (obj == null)
{
return default(T);
}
Type type = obj.GetType();
object copy = Activator.CreateInstance(type);
// 获取所有字段和属性信息,并将源对象中的值复制到目标对象中
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
object value = fieldInfo.GetValue(obj);
fieldInfo.SetValue(copy, DeepCopy(value));
}
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
if (!propertyInfo.CanWrite || !propertyInfo.CanRead)
{
continue;
}
object value = propertyInfo.GetValue(obj);
propertyInfo.SetValue(copy, DeepCopy(value));
}
return (T)copy;
}
复制代码
手动赋值
手动复制所有成员变量
可以手动编写代码复制对象中的所有成员变量,这需要对对象结构有很好的了解,并且比较繁琐,容易漏掉某些成员。
public class Person
{
public string Name;
public int Age;
public Person DeepCopy()
{
Person copy = new Person();
copy.Name = this.Name;
copy.Age = this.Age;
return copy;
}
}
复制代码
ICloneable 接口
实现 ICloneable 接口
可以在对象中实现 ICloneable 接口,并重写 Clone 方法来实现深拷贝。重写的 Clone 方法内可以调用上述任何一种方案。
public class Person : ICloneable
{
public string Name;
public int Age;
public object Clone()
{
Person copy = new Person();
copy.Name = this.Name;
copy.Age = this.Age;
return copy;
}
}
复制代码
第三方库
还有一种方式是使用第三方库实现深拷贝,例如 AutoMapper、ValueInjecter 等。这些库可以自动复制对象中的所有成员变量,从而实现深拷贝。
其中比较常用的包括:
AutoMapper:这是一个非常流行的对象映射库,可以用于将一个对象的属性值复制到另一个对象中,从而实现对象深拷贝。
Newtonsoft.Json:这是一个广泛使用的 JSON 序列化/反序列化库,它也提供了一些方法来实现对象深拷贝。
Cloneable:这是一个专门为 .NET 平台设计的对象克隆库,它提供了多种深拷贝和浅拷贝的方式。
FastDeepCloner:这是一个高性能的对象复制库,它支持对任意类型进行深拷贝,并且提供了多种可配置选项。
可以需要根据自己的具体需求选择适合自己的库。如果只是需要简单的深拷贝操作,那么 AutoMapper 和 Newtonsoft.Json 都是不错的选择;如果需要更加高效、灵活的操作,那么可以考虑使用 FastDeepCloner 或 Cloneable 等库。
来源:
https://www.cnblogs.com/pandefu/archive/2023/08/13/17536258.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
上一篇:
开源.NetCore通用工具库Xmtool使用连载 - HTTP请求篇
下一篇:
WPF 入门笔记 - 07 - MVVM示例
发表于 2023-8-13 17:59:31
举报
回复
使用道具
分享
返回列表
发新帖
本版积分规则
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
快速回复
快速回复
返回顶部
返回顶部
返回列表
返回列表