因为对表达式树有点兴趣,出于练手的目的,试着写了一个深拷贝的工具库。支持.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. leetcode849

    public class Solution { public int MaxDistToClosest(int[] seats) { ; var len = seats.Length; ) { ; } ...

  2. Mysql 5.6 源码编译安装

    简介: 多余的话不说,就是源码安装 Mysql 5.6 ,机器内存 512 MB ,系统 CentOS 6.6 ,安装方式 minimal ! 1.安装底层支持包 shell > yum -y ...

  3. 不同应用场景的10个Linux面试问题与解答

    本文由 极客范 - 小道空空 翻译自 Avishek Kumar.欢迎加入极客翻译小组,同我们一道翻译与分享.转载请参见文章末尾处的要求. 这一次我们不再介绍某个特定主题的Linux面试问题,而是随机 ...

  4. Ubuntu设置开机启动服务

    一.查看当前的运行级别 runlevel 二.加载服务 $ cd /etc/init.d $ sudo update-rc.d test defaults 95 三.增加默认启动脚本 sudo vi ...

  5. Linux实战教学笔记14:用户管理初级(上)

    第十四节 用户管理初级(上) 标签(空格分隔): Linux实战教学笔记-陈思齐 ---更多资料点我查看 1,账号管理 1.1 管理用户命令汇总 命令 注释说明(特殊颜色的必须掌握) useradd增 ...

  6. alinode 配置 pm2

    今天公司要配置阿里的一个node.js性能监控(alinode),这个东西看似配置很简单但是你不知道你配置对没对, 因为他需要1分钟后才能显示出来,而且模块依赖我等了10分钟才出来, 文档的链接htt ...

  7. 混合开发之iOS快速集成DSBridge

    DSBridge-IOS github:https://github.com/wendux/DSBridge-IOS 使用 Native 实现API 代理类 //JsApiTest.m @implem ...

  8. AJAX(XMLHttpRequest)进行跨域请求方法详解

    AJAX(XMLHttpRequest)进行跨域请求方法详解(三) 2010年01月11日 08:48:00 阅读数:24213 注意:以下代码请在Firefox 3.5.Chrome 3.0.Saf ...

  9. Canny效果

  10. 修改字段注释modify

    alter table test1 modify 字段名 类型 comment '修改后的字段注释'; ALTER TABLE tc_activity_miaosha MODIFY `validity ...