如果通过 C# 实现对象的深复制 ?

咨询区

  • NakedBrunch

我想实现 引用类型对象 之间的深复制,也就是在新的对象上修改不会影响到老的对象,我用了 C# 提供的 Clone 方法。

MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();

但貌似这样行不通,请问该如何正确实现?

回答区

  • craastad

如果你的引用类型对象是 json 友好的,那你完全可以借助第三方工具将其转为 Json,比如 Json.NET ,参考如下的 Clone 扩展方法。

public static T Clone<T>(this T theObject)
{string jsonData = JsonConvert.SerializeObject(theObject);return JsonConvert.DeserializeObject<T>(jsonData);
}

然后像下面这样使用。

NewObject = OldObject.Clone();
  • Stacked

如果你要快速实现,建议使用对象映射化工具 AutoMapper, 它是一个高效并且轻量级的将一个对象转为另一个对象,它的底层使用的是 Lambda 表达式树,参考如下代码:

MyType source = new MyType();
Mapper.CreateMap<MyType, MyType>();
MyType target = Mapper.Map<MyType, MyType>(source);

上面的target就是深copy后的对象,如果你觉得这样还繁琐的化,再封装到一个扩展方法中去。

public static T Copy<T>(this T source)
{T copy = default(T);Mapper.CreateMap<T, T>();copy = Mapper.Map<T, T>(source);return copy;
}

然后像下面这样使用。

MyType copy = source.Copy();
  • Marcell Toth

通常来说,做深层的copy,方法有如下几种。

  1. 序列化

本质上来说,序列化是非常慢的一种方式,而且还限制重重,比如说:

  1. BinaryFormatter 需要引用类型必须实现 Serializable 特性。

  2. JsonConverter 需要引用类型必须有无参构造函数。

  1. 表达式树

要先加速,可以使用 Expression Tree 或者 Reflection.Emit 来动态生成深复制代码,但这种原始的方式实现起来特别麻烦,我为此专门写了一个映射工具,参见 github:https://github.com/marcelltoth/ObjectCloner

实现起来非常方便,参考如下代码:

var clone = ObjectCloner.DeepClone(original);

我的方法 ~3x 于 Reflection, ~12x 于 Newtonsoft.Json 。

点评区

其实 Dapper 用的就是 Emit 来实现高速映射, AutoMapper 用的是 Expresstion Tree 实现高速映射,大家有兴趣可以了解下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos安装与配置R语言

Linux下安装R语言 一、编译安装 由于采用编译安装&#xff0c;所以需要用到gcc编译环境&#xff0c;在编译前check文件时还会用到libXt-devel和readline-devel两个依赖&#xff0c;所以在编译R语言源码时先将这些工具和依赖包准备好。readline-devel 也可以不安装&#xff0c;不…

python beautifulsoup4 table tr_python BeautifulSoup解析表

牧羊人nacy这是通用的工作示例(表数据)标记。它返回带有内部列的行的列表。第一行仅接受一个(表头/数据)。def tableDataText(table): rows [] trs table.find_all(tr) headerow [td.get_text(stripTrue) for td in trs[0].find_all(th)] # header row i…

linux之让终端支持C++11/14编译cpp文件

1 问题 我们的项目很多智能指针,但是我linux的终端肯定不支持C11/14, 我们平时都是用的下面的命令编译c文件 g -g file.cpp -o file r 如果是用c11编译需要改成如下 g -g -Wall -stdc11 file.cpp -o file 如果是用C14编译需要改成如下 g -g -Wall -stdc14 file.cpp -o f…

clob字段怎么导出_Oracle 11g及12c+版本下为啥有些表不能exp导出?

【引言】今天有同事问了一个问题&#xff0c;在Oracle 11g下&#xff0c;为啥exp方式导出一个用户的数据表&#xff0c;在imp后却发现有些表并没有迁移过来。经查阅官方文档&#xff0c;发现和Oracle11g及12c 版本相对于10g&#xff0c;有一个新特性deferred_segment_creation(…

Python中第三方的库(library)、模块(module),包(package)的安装方法以及ImportError: No module named...

Python中&#xff0c;想要安装第三方安装包&#xff0c;即third library&#xff0c;package等&#xff0c;对于熟悉的人来说&#xff0c;很简单。但是对于新手&#xff0c;至少对于之前的我&#xff0c;很难&#xff0c;往往只是安装一个很小的包&#xff0c;都被搞得一头雾水…

C# 读写二进制文件

读写二进制文件的一种选择是直接使用流类型&#xff1b;在这种情况下&#xff0c;最好使用字节数组执行读写操作。另一个选择是使用为这个场景定义的读取器和写入器&#xff1a;BinaryReader和BinaryWriter。使用它们的方式类似于使用 StreamReader 和 StreamWriter&#xff0c…

推荐系统(1)--splitting approaches for context-aware recommendation

开篇语&#xff1a; 大一的时候。在实验室老师和师兄的带领下。我開始接触推荐系统。时光匆匆&#xff0c;转眼已是大三&#xff0c;因为大三课甚是少。于是便有了时间将自己所学的东西做下总结。第一篇博客。献给过去三年里带我飞的老师和师兄们&#xff0c;感谢你们的无私帮助…

C++之智能指针std::shared_ptr简单使用和理解

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程 1 智能指针std::shared_ptr相关知识和如何使用 我们这里先说下智能指针std::shared_ptr,因为我看到我我们项目c++代码里面用得很多,我不是不会,所以记录学习下 先让ubu…

Excel只能输入不能修改

一、选择需要加密的单元格&#xff0c;右键→设置单元格格式→保护→锁定&#xff1b; 二、按AltF11键进入VBE环境&#xff0c;在左侧的相应sheet名称上&#xff08;如sheet1&#xff09;右键→查看代码&#xff1b; 三、选择Worksheet的SelectionChange事件&#xff0c;写入…

python 百度云文字识别 proxy_python使用百度文字识别功能方法详解

介绍python使用百度智能去的文字识别功能&#xff0c;可以识别截图中的文&#xff0c;登陆路验证码等等。&#xff0c; 登陆百度智能云&#xff0c;选择产品服务。选择“人工智能”---文字识别。点击创建应用。 如图下面有关于“文字识别”的各类信息&#xff0c;如通用文字识别…

Android性能优化典范(转)

本文转自&#xff1a;http://hukai.me/android-performance-patterns/ 2015新年伊始&#xff0c;Google发布了关于Android性能优化典范的专题&#xff0c;一共16个短视频&#xff0c;每个3-5分钟&#xff0c;帮助开发者创建更快更优秀的Android App。课程专题不仅仅介绍了Andr…

Xamarin效果第二十一篇之GIS中可扩展浮动操作按钮

在前面文章中简单玩了玩GIS的基本操作、Mark相关、AR、测距和加载三维白模,今天再次对操作栏又一次修改了,直接放到了右下角可伸缩效果;啥也不说了都在效果里:添加支持圆角 ContentView:Xamarin.Forms.PancakeView再来Xamarin 社区工具包:Xamarin.CommunityToolkit再来看看最终…

LeetCode 3_Longest Substring Without Repeating Characters

LeetCode 3_Longest Substring Without Repeating Characters 题目描写叙述&#xff1a; Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" …

ASP.NET 连接MySql数据库

ASP.NET Mysql操作类 以下连接MySql数据库以VS2010为例&#xff0c;对于其他的编辑器也差不多 1. 我们需要在Mysql官网下载一个组件http://dev.mysql.com/downloads/connector/net/ 下载最新版的即可&#xff0c;并且安装connector&#xff0c;其实仅仅只是为了得到Mysql.Data…

linux之安装boost环境

1 下载最新的boost代码包 网址www.boost.org,如果觉得网速很慢,你可以直接在别人的csdn那里去下载 地址:https://download.csdn.net/download/weixin_42404995/10508611,我这里就是用的这个boost_1_67_0.tar.gz 2 安装boost环境 1) 解压boost_1_67_0.tar.gz之后进入boost目…

IDL 自定义函数

function add,x,yreturn, xy endpro sumx1y2print,add(x,y) end

java反射有什么用_java反射的作用知识点总结

Java的反射机制是Java特性之一&#xff0c;反射机制是构建框架技术的基础所在。灵活掌握Java反射机制&#xff0c;对大家以后学习框架技术有很大的帮助。什么是Java的反射&#xff1f;反射是Java的特征之一&#xff0c;是一种间接操作目标对象的机制。JAVA反射机制是在运行状态…

【新版发布】ComponentOne 新增 .NET 6 和 Blazor 平台控件支持

ComponentOne Enterprise是葡萄城推出的一款内置 300 多种开发控件的 .NET控件集&#xff0c;可满足 WinForm、WPF、Blazor、ASP.NET MVC 等平台下的系统开发需求&#xff0c;提供表格数据管理、数据可视化、报表和文档等功能&#xff0c;被开发人员誉为“.NET开发的‘瑞士军刀…

python多进程和多线程一起使用_Python3多进程与多线程区别及使用(2.线程)

threading模块 简述&#xff1a; threading模块 threading.currentThread(): 返回当前的线程变量。 threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前&#xff0c;不包括启动前和终止后的线程。 threading.activeCount(): 返回正在运行…

Ruby如何成长成高性能系统构架

为什么80%的码农都做不了架构师&#xff1f;>>> 结束了一份Ruby为主的工作,想把个方面总结一下,这篇是关于系统性能方面的.以下数据都是简单回忆的数据,加之企业保密数据的需要,和精确数有些出入,仅供参考. 说起Ruby的性能,无论从官方到社区,都公认是劣于其它的框架…