c#用表達式樹實現深拷貝功能

来源:https://www.cnblogs.com/blurhkh/archive/2018/04/06/8728866.html
-Advertisement-
Play Games

因為對錶達式樹有點興趣,出於練手的目的,試著寫了一個深拷貝的工具庫。支持.net standard2.0或.net framework4.5及以上。 GitHub地址https://github.com/blurhkh/DeepCopier nuget地址https://www.nuget.org/ ...


因為對錶達式樹有點興趣,出於練手的目的,試著寫了一個深拷貝的工具庫。支持.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 = 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();


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近工作業務要是用伺服器證書驗證,在這裡記錄下一. 1.添加伺服器角色 [證書服務] 2.一路下一步直到證書服務安裝完成; 3.選擇圈選中的伺服器證書 4.點擊[創建證書申請] 5.填寫信息 6.下一步,直到保存文件位置 7.搜索證書頒發機構,打開 8.右鍵樹型,選擇[提交一個新的申請] 9.選擇之 ...
  • 主題 賬戶管理一個比較常見的功能就是密碼強度策略,Identity已經內置了一個通用的可配置的策略,我們一般情況下可以直接拿來用即可。本篇我會介紹一些Identity內置的密碼策略類:PasswordValidator,並且簡單介紹一下源碼。最好我們還會自定義一個密碼策略類的實現。https://w ...
  • sing System;using System.Collections.Generic;using System.Linq;using System.Text; namespace ConsoleApplication1{ class Program { static void Main(stri ...
  • C#情懷與未來,怨天尤人還是抓住機會,能否跟上dnc新時代浪潮? 經常看到有.NET圈子在討論是否應該轉其它語言 C#情懷是一方面,如果覺得C#未來沒前途,光靠情懷是撐不住的, 建議對C#未來沒信心的朋友,轉go、rust、py、TS、JS、java …… 常常看到有人抱怨.NET,抱怨好幾年了,卻 ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplicationl { class Program { static void Main ...
  • 本文介紹了 C# 如何使用 GDI+ 為圖片添加文字,並且可以使文字字體大小自適應。 ...
  • c#的三個高級參數ref out 和Params 前言:在我們學習c#基礎的時候,我們會學習到c#的三個高級的參數,分別是out .ref 和Params,在這裡我們來分別的講解一下,在這裡的我們先不做具體的解釋,我會通過幾個例子來做分別的解釋。 一:out參數 1.首先我先給大家一個題:我們來寫一 ...
  • 這篇文章主要介紹了C#中is與as的區別,較為詳細的分析了is與as的原理與特性及用法區別,具有很好的學習借鑒價值,需要的朋友可以參考下 本文實例分析了C#中is與as的區別,分享給大家供大家參考。具體分析如下: 一、C#類型的轉換 在c#中類型的轉換分兩種:顯式和隱式,基本的規則如下: 1、基類對 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...