因为对表达式树有点兴趣,出于练手的目的,试着写了一个深拷贝的工具库。支持.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#用表达式树实现深拷贝功能的更多相关文章

  1. C#使用表达式树动态调用方法并实现99乘法表

    我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...

  2. 【C#表达式树 四】Expression类上的函数列表

    Expression相当于工厂,这个工厂有各式各样的模型(函数),用来生成各种零部件(节点类型),最后组装成表达式树. Expressions这个命名空间有各种个容器用陈放生产出来的零部件. Expr ...

  3. C#3.0新增功能10 表达式树 01 简介

    连载目录    [已更新最新开发文章,点击查看详细] 如果你使用过 LINQ,则会有丰富库(其中 Func 类型是 API 集的一部分)的经验. (如果尚不熟悉 LINQ,建议阅读 LINQ 教程,以 ...

  4. C#3.0新增功能10 表达式树 02 说明

    连载目录    [已更新最新开发文章,点击查看详细] 表达式树是定义代码的数据结构. 它们基于编译器用于分析代码和生成已编译输出的相同结构.表达式树和 Roslyn API 中用于生成分析器和 Cod ...

  5. C#3.0新增功能10 表达式树 03 支持表达式树的框架类型

    连载目录    [已更新最新开发文章,点击查看详细] 存在可与表达式树配合使用的 .NET Core framework 中的类的大型列表. 可以在 System.Linq.Expressions 查 ...

  6. C#3.0新增功能10 表达式树 05 解释表达式

    连载目录    [已更新最新开发文章,点击查看详细] 表达式树中的每个节点将是派生自 Expression 的类的对象. 该设计使得访问表达式树中的所有节点成为相对直接的递归操作. 常规策略是从根节点 ...

  7. C#3.0新增功能10 表达式树 06 生成表达式

    连载目录    [已更新最新开发文章,点击查看详细] 到目前为止,你所看到的所有表达式树都是由 C# 编译器创建的. 你所要做的是创建一个 lambda 表达式,将其分配给一个类型为 Expressi ...

  8. C#3.0新增功能10 表达式树 07 翻译(转换)表达式

    连载目录    [已更新最新开发文章,点击查看详细] 本篇将介绍如何访问表达式树中的每个节点,同时生成该表达式树的已修改副本. 以下是在两个重要方案中将使用的技巧. 第一种是了解表达式树表示的算法,以 ...

  9. C#3.0新增功能10 表达式树 04 执行表达式

    连载目录    [已更新最新开发文章,点击查看详细] 表达式树 是表示一些代码的数据结构. 它不是已编译且可执行的代码. 如果想要执行由表达式树表示的 .NET 代码,则必须将其转换为可执行的 IL ...

随机推荐

  1. AO Identify地图交互

    转自supernever文章 Identify 1.框选要素高亮显示 private void axMapControl1_OnMouseDown(object sender, ESRI.ArcGIS ...

  2. Python 格式化输出 ( 颜色 )

    简介: Python 中如果想让输出有颜色显示,实现起来还是挺容易的,你需要拥有 termcolor 的知识! 参考地址:https://pypi.python.org/pypi/termcolor/ ...

  3. tomcat的配置文件server.conf中的元素的理解

    tomcat的配置文件server.conf中的元素的理解 tomcat作为一个servlet服务器本身的配置文件是tomcat_home/conf/server.conf,这个配置文件中有很多元素, ...

  4. Linux实战教学笔记30:Nginx反向代理与负载均衡应用实践

    1.1 集群简介 简单地说,集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服务器.这些服务器之间可 ...

  5. 阿里巴巴Java开发规约扫描插件-Alibaba Java Coding Guidelines 在idea上安装使用教程

    经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的<阿里巴巴Java开发规约>扫描插件!该插件由阿里巴巴P3C项目组研发.P3C是世界知名的反潜机,专门对付 ...

  6. hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)

    http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java ...

  7. controller,service,repository,component注解的使用对比

    项目中的controller层使用@controller注解 @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象.分发处理器将会扫描使用了 ...

  8. RPM简介与基本使用

    一.什么是RPM RPM的全名是Red Hat Package Manager,本意是Red Hat 软件包管理,顾名思义是Red Hat 贡献出来的软件包管理:在Fedora .Redhat.Man ...

  9. windows命令行下批量拷贝同一后缀的文件到另外一个目录

    一个目录下有很多文件夹,想拷贝每个文件夹下面的wmv文件到另外一个目录,如果鼠标打开一个文件,拷贝一个,再打开其他的,逐一操作,很麻烦的,百度了一下,xcopy命令就可以实现:例如将C盘x1目录下所有 ...

  10. xgboost 里边的gain freq, cover

    assuming that you're using xgboost to fit boosted trees for binary classification. The importance ma ...