首页 > 编程语言 >c#用表达式树实现深拷贝功能

c#用表达式树实现深拷贝功能

时间:2023-06-15 10:00:48浏览次数:46  
标签:Console Author c# sw book new 拷贝 public 表达式

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

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 = 0; i < 1000000; i++)
            {
                bookDTO = AutoMapper.Mapper.Map<Book, BookDTO>(book);
            }
            Console.WriteLine($"AutoMapper costed {sw.ElapsedMilliseconds} ms at 1st time.");

            sw.Restart();

            for (int i = 0; i < 1000000; 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 = 0; i < 1000000; i++)
            {
                temp = DeepCopy.DeepCopier.Copy(book);
            }
            Console.WriteLine($"DeepCopy costed {sw.ElapsedMilliseconds} ms at 1st time.");

            sw.Restart();

            for (int i = 0; i < 1000000; i++)
            {
                temp = DeepCopy.DeepCopier.Copy(book);
            }
            Console.WriteLine($"DeepCopy costed {sw.ElapsedMilliseconds} ms at 2nd time.");
            Console.ReadLine();
复制代码

 

 

出处:https://www.cnblogs.com/eventhorizon/p/8728866.html

标签:Console,Author,c#,sw,book,new,拷贝,public,表达式
From: https://www.cnblogs.com/mq0036/p/17482079.html

相关文章

  • DAC+定时器 生成正弦波,三角波
    正弦波生成配置如下DAC触发trigger是由TIM2事件触发。 TIM2配置方式/***生成正弦波数据点函数*@paramNPoints�???个周期内的点�???*@paramVMaxRange输出的电压最大�?�,取�?�范�???0~3.3V*@paramSineWaveTable存放生成的数据点*/voidSineWaveGen......
  • Excel Undo-Redo的编程问题
    ExcelUndo历史栈对外是不透明的。代码对Excel表单的编辑操作会清空Excel内部的Undo历史。Application.OnUndo只支持一次撤销,并且不支持ReDo。使用DDE的方式支持Undo/Redo是现在发现的最佳方案。DDE的问题:异步的,因此和用户在界面上的操作容易产生混乱。需要同步化,但是编程比......
  • Pixelmator Pro for Mac(媲美PS的修图软件)
    PixelmatorProMac版是一款功能强大的PhotoshopMac版替代品,它能轻松地为照片和视频添加任何更改。它提供了一套革命性的工具,可以帮助您在任何照片,视频或幻灯片上进行更改。所有这些工具都非常快速有效。使用PixelmatorPro,您可以轻松地将照片和视频从普通的Photoshop中提取出......
  • Oracle-日期时间
    sysdate1.获取当前时间:selectsydatefromdual;--2023-06-159:38:16selecttrunc(sysdate+1)fromdual;--明天2023-06-16通过trunc截断时间,只保留日期部分selecttrunc(sysdate-1)fromdual;--昨天selecttrunc(sysdate)+12/24fromdual;--2023-06-1512:00:00,......
  • Three.js教程:相机控件轨道控制器OrbitControls
    推荐:将NSDT场景编辑器加入你的3D工具链其他系列工具:NSDT简石数字孪生相机控件轨道控制器OrbitControls平时开发调试代码,或者展示模型的时候,可以通过相机控件OrbitControls实现旋转缩放预览效果。OrbitControls使用你可以打开课件案例源码测试下效果。旋转:拖动鼠标左键缩放......
  • c++ mutex
    mutex直译为互斥量。使用它可以做到:一份共享数据,同时只能由一个线程访问,在此基础上会衍生很多很方便的api,通过mutex将共享数据的访问变成互斥操作,避免与时间相关的错误简单结论及定义:1.每个线程在对资源操作前都尝试先加锁,加锁成功才能操作,操作结束就解锁 2. ......
  • Nginx [emerg] listen() to 0.0.0.0:80, backlog 511 failed (98: Address already in
    Nginx更新后经常遇到这样的问题,解决方法:123fuser-k80/tcp&&/etc/init.d/nginxstart或killall-9nginx&&/etc/init.d/nginxstart......
  • 给你的 Discord 接入一个既能联网又能画画的 ChatGPT
    如果有这样一款Discord机器人,它既能访问互联网,又能绘画,还能给YouTube视频提供摘要。最重要的是,它是完全免费的,不需要提供OpenAI的APIKey,我就问你香不香?现在就有这样一款机器人,你用还是不用?DiscordAIChatbot上链接:https://github.com/mishalhossin/Discord-AI-Chatbot......
  • docker安装与使用教程
    https://mp.weixin.qq.com/s?__biz=MjM5NTY1MjY0MQ==&mid=2650860524&idx=3&sn=02dfc31d637f70b066a6ef9842beeac5&chksm=bd017ea28a76f7b466773e68f7dab26e65ffae2918c28aa1d87c84acfc54460a7b82aa57279f&scene=27  官方的一键安装方式:curl -fsSL https://ge......
  • C#中使用CAS实现无锁算法
    CAS的基本概念CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问。它操作通常包含三个参数:一个内存地址(通常是一个共享变量的地址)、期望的旧值和新值。CompareAndSwap(内存地址,期望的旧值,新值)CAS操作会比较内存地址处的值与期望......