因为对表达式树有点兴趣,出于练手的目的,试着写了一个深拷贝的工具库。支持.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. HALCON初步:文件夹遍历,文件筛选,文件名拆分,图片读取及保存

    [1]文件夹遍历 list_image_files ( : : ImageDirectory, Extensions, Options : ImageFiles) ImageDirectory: 文件 ...

  2. 使用COM口的2、3针的通断作为中端源(有一个读图像的摄像头,当把卡插到位时触发中端,防止在插卡的过程中出现不稳定的图像)

    利用串口2读,串口3发数据的特点.建立不断的发送流,再从接收端接收.如果收到,则数据畅通,否则断开.相当于产生一个中断.这样电脑对外部事件可作出反应. using System;using Syste ...

  3. how to use jquery with primefaces

    PrimeFaces already ships with jQuery bundled, yet you've downloaded and installed another one which ...

  4. SQL 语句中的in、find_in_set、like的区别

    1.in查询相当于多个or条件的叠加,例如: select * from user where user_id in (1,2,3);等效于select * from user where user_ ...

  5. shell编程——sed用法

    一.sed格式: sed 参数 '正则表达式' 文件名 演示文件的内容: [root@localhost ~]# cat test.sh #!/bin/bash 第一行 12345! 第二行 2345 ...

  6. html 资源

  7. Java-精确计算工具类

    import java.math.BigDecimal; import java.math.RoundingMode; /** * 精确计算工具类(加,减,乘,除,返回较大值,返回较小值) */ pu ...

  8. 746. Min Cost Climbing Stairs 最不费力的加权爬楼梯

    [抄题]: On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once yo ...

  9. [c++] polymorphism without virtual function

    polymorphism without virtual function

  10. Cw210开发板

    达内培训嵌入式开发板 qt + kernel uboot toolchain