c#用表达式树实现深拷贝功能
因为对表达式树有点兴趣,出于练手的目的,试着写了一个深拷贝的工具库。支持.net standard2.0或.net framework4.5及以上。
GitHub地址https://github.com/blurhkh/DeepCopier
nuget地址https://www.nuget.org/packages/DeepCopier
使用方法如下:
首先创建几个测试用的类型
public class Author
{
public string Name { get; set; }
} public class Book
{
public string Title { get; set; }
public Author Author { get; set; }
public List<string> Tags { get; set; }
} public class BookDTO
{
public string Title { get; set; }
public Author Author { get; set; }
public List<string> Tags { get; set; }
}
Book book = new Book
{
Author = new Author { Name = "Author" },
Title = "Title",
Tags = new List<string> { "dotnet-core", "c#" }
}; // 用法1 深拷贝一个对象
Book book2 = Copier.Copy(book);
// 或一个IEnumerable<T>的实现类实例(目前仅支持一维数组和ICollection<T>的实现类)
HashSet<Book> books = new HashSet<Book>() { book, book };
HashSet<Book> books2 = Copier.Copy(books); // 用法2 新建目标类型实例,并将源对象的属性值拷贝至目标对象的对应属性
BookDTO bookDTO = Copier.Copy<Book, BookDTO>(book); // 用法3 将源对象的属性值拷贝至已存在的目标对象的对应属性
BookDTO target = new BookDTO();
Copier.Copy(book, target);
同类的工具库比如较为常见的AutoMapper和一个Reflection.Emit操作IL写的DeepCopy(https://www.nuget.org/packages/DeepCopy/)
接下来进行一下和他们的性能对比,测试数据采用上面的Book类型,循环次数为100万次。
测试数据如下:
Book book = new Book
{
Author = new Author { Name = "Author" },
Title = "Title",
Tags = new List<string> { "dotnet-core", "c#" }
};
测试内容如下(本人PC的CPU为I7 4790k,不同库的测试代码分别跑在不同的程序里):
首先和AutoMapper进行对比
BookDTO bookDTO = null;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
bookDTO = DeepCopier.Copier.Copy<Book, BookDTO>(book);
}
Console.WriteLine($"DeepCopier costed {sw.ElapsedMilliseconds} ms at 1st time.");
sw.Restart();
for (int i = 0; i < 1000000; i++)
{
bookDTO = DeepCopier.Copier.Copy<Book, BookDTO>(book);
}
// 因为有了前一次的缓存,这里速度会更快
Console.WriteLine($"DeepCopier costed {sw.ElapsedMilliseconds} ms at 2nd time.");
Console.ReadLine();

// AutoMapper需要提前配置
AutoMapper.Mapper.Initialize(config => {
config.CreateMap<Book, BookDTO>();
}); BookDTO bookDTO = null; Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = ; i < ; i++)
{
bookDTO = AutoMapper.Mapper.Map<Book, BookDTO>(book);
}
Console.WriteLine($"AutoMapper costed {sw.ElapsedMilliseconds} ms at 1st time."); sw.Restart(); for (int i = ; i < ; i++)
{
bookDTO = AutoMapper.Mapper.Map<Book, BookDTO>(book);
}
Console.WriteLine($"AutoMapper costed {sw.ElapsedMilliseconds} ms at 2nd time.");
Console.ReadLine();

// DeepCopy只支持对自身类型的拷贝
Book temp = null; Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = ; i < ; i++)
{
temp = DeepCopy.DeepCopier.Copy(book);
}
Console.WriteLine($"DeepCopy costed {sw.ElapsedMilliseconds} ms at 1st time."); sw.Restart(); for (int i = ; i < ; i++)
{
temp = DeepCopy.DeepCopier.Copy(book);
}
Console.WriteLine($"DeepCopy costed {sw.ElapsedMilliseconds} ms at 2nd time.");
Console.ReadLine();

c#用表达式树实现深拷贝功能的更多相关文章
- C#使用表达式树动态调用方法并实现99乘法表
我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...
- 【C#表达式树 四】Expression类上的函数列表
Expression相当于工厂,这个工厂有各式各样的模型(函数),用来生成各种零部件(节点类型),最后组装成表达式树. Expressions这个命名空间有各种个容器用陈放生产出来的零部件. Expr ...
- C#3.0新增功能10 表达式树 01 简介
连载目录 [已更新最新开发文章,点击查看详细] 如果你使用过 LINQ,则会有丰富库(其中 Func 类型是 API 集的一部分)的经验. (如果尚不熟悉 LINQ,建议阅读 LINQ 教程,以 ...
- C#3.0新增功能10 表达式树 02 说明
连载目录 [已更新最新开发文章,点击查看详细] 表达式树是定义代码的数据结构. 它们基于编译器用于分析代码和生成已编译输出的相同结构.表达式树和 Roslyn API 中用于生成分析器和 Cod ...
- C#3.0新增功能10 表达式树 03 支持表达式树的框架类型
连载目录 [已更新最新开发文章,点击查看详细] 存在可与表达式树配合使用的 .NET Core framework 中的类的大型列表. 可以在 System.Linq.Expressions 查 ...
- C#3.0新增功能10 表达式树 05 解释表达式
连载目录 [已更新最新开发文章,点击查看详细] 表达式树中的每个节点将是派生自 Expression 的类的对象. 该设计使得访问表达式树中的所有节点成为相对直接的递归操作. 常规策略是从根节点 ...
- C#3.0新增功能10 表达式树 06 生成表达式
连载目录 [已更新最新开发文章,点击查看详细] 到目前为止,你所看到的所有表达式树都是由 C# 编译器创建的. 你所要做的是创建一个 lambda 表达式,将其分配给一个类型为 Expressi ...
- C#3.0新增功能10 表达式树 07 翻译(转换)表达式
连载目录 [已更新最新开发文章,点击查看详细] 本篇将介绍如何访问表达式树中的每个节点,同时生成该表达式树的已修改副本. 以下是在两个重要方案中将使用的技巧. 第一种是了解表达式树表示的算法,以 ...
- C#3.0新增功能10 表达式树 04 执行表达式
连载目录 [已更新最新开发文章,点击查看详细] 表达式树 是表示一些代码的数据结构. 它不是已编译且可执行的代码. 如果想要执行由表达式树表示的 .NET 代码,则必须将其转换为可执行的 IL ...
随机推荐
- Arduino教程资料汇总(8月22日悄悄跟新了一下)
http://www.geek-workshop.com/thread-985-1-1.html 本帖最后由 迷你强 于 2013-8-31 12:36 编辑 =====F-101 arduino基础 ...
- 「小程序JAVA实战」java-sesion的状态会话与无状态会话(38)
转自:https://idig8.com/2018/09/02/xiaochengxujavashizhanjava-sesiondezhuangtaihuihuayuwuzhuangtaihuihu ...
- nginx启动、重启、重新加载配置文件和平滑升级
Nginx有一个主进程和几个工作进程,主进程的主要作用就是读取.评估配置文件和管理工作进程,工作进程对请求做实际处理.工作进程的数量是在配置文件中配置的,一般设置为cpu的核心数*线程数. nginx ...
- <转>linux操作系统编程——共享内存读写(采用信号量进行同步互斥)
http://blog.csdn.net/yanghaoran321/article/details/7872722 程序要求: 创建一个写端和一个读端,写端写入数据后读端才开始读,读端读完数据后,写 ...
- 对excel进行封装
package com.huawei.utils; import java.io.FileNotFoundException;import java.io.FileOutputStream;impor ...
- Linux实战教学笔记55:开源虚拟化KVM(三)管理虚拟网络
六,管理虚拟网络 [x] Linux网桥基本概念 [x] qemu-kvm支持的网络 [x] 向虚拟机添加虚拟网络连接 [x] 基于NAT的虚拟网络 [x] 基于网桥的虚拟网络 [x] 用户自定义的隔 ...
- java算法 第七届 蓝桥杯B组(题+答案) 9.取球博弈
9.取球博弈 (程序设计) 两个人玩取球的游戏.一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目.如果无法继续取球,则游戏结束.此时,持有奇数个球的一方获胜.如果两人都是 ...
- css readonly和disabled的区别
一.前言 要说readonly和disabled的区别,就需要先说说两者的联系: 两个属性都可以作用于input等表单元素上,都使得元素成为“不可用”的状态: 两者的字面意义先介绍一下: readon ...
- OceanBase
OceanBase 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! OceanBase是一个支持海量数据的高性能分布式数据库系统,实现了 数千亿条记录.数百TB数据上的 ...
- 270. Closest Binary Search Tree Value 二叉搜索树中,距离目标值最近的节点
[抄题]: Given a non-empty binary search tree and a target value, find the value in the BST that is clo ...