C# Deconstruct | 簡化元組與對象的數據提取

官方文檔:析構元組和其他類型 - C# | Microsoft Learn

標簽:Deconstruct、Tuple、record、模式匹配

PS:record相關內容后續還會繼續更新🔄

模式匹配可以查看我的另一篇👉模式匹配

目錄

    • 1. 概述
    • 2. 基本用法
      • 2.1 元組解構
      • 2.2丟棄符
    • 3. 進階使用
      • 3.1 為自定義類型添加解構能力
          • 1. 為 `Person` 類實現解構
          • 2 擴展方法解構
      • 3.2 與記錄(record) 的協同
      • 3.3 與模式匹配的聯動(C# 8+)
    • 4. 限制與最佳實踐
    • 5. 總結

1. 概述

Deconstruct(解構) 是 C# 7.0 引入的語法糖, 允許以簡潔的語法從元組或對象中提取多個數據成員,避免逐個訪問字段的繁瑣操作。

它讓元組、自定義類型、記錄(record)等數據的“拆包”變得非常直觀。

核心思想:將一個復合對象“拆分”成其組成部分。

關鍵詞

  • Deconstruct 方法(實例或擴展方法)
  • 解構賦值(Deconstruction Assignment)
  • 丟棄符 _ (discard)
  • 元組 (T1, T2, …) 的隱式解構

2. 基本用法

2.1 元組解構

元組(Tuple)自帶的解構支持是最直接的應用。

// 創建一個元組
var person = ("Alice", 30);
  1. 顯式指定類型

    (string name1, int age1) = person; // 顯式類型聲明并解構
    
  2. 一次性聲明并解構 (最常見)

    var (name2, age2) = person; // 使用 var 推斷類型聲明并解構
    

    也支持混合使用顯式與 var 聲明(但不建議):

    (string name3, var age3) = person;
    
  3. 析構到已聲明的變量混合聲明與賦值

    string name4 = "Eoch";
    (name4,  int age4) = person
    
  4. 變換:元組的解構與構造

    1. 構造 (Construction):等號右邊 (b, a)構造一個新的元組,這個元組的兩個元素分別是當前變量 ba 的值
    2. 解構 (Deconstruction):等號左邊 (a, b)解構這個新元組,將其元素按順序賦值給變量 ab
    int a = 5, b = 10;
    (a, b) = (b, a); // a 現在是 10, b 現在是 5
    

2.2丟棄符

在處理解構時,可能只對對象的一部分數據感興趣。

C# 提供了 棄元(_ 來忽略不關心的輸出參數,,其值將被忽略,使代碼意圖更清晰。

Person person = new Person("Bruce", "Banner", 40);// 只解構出 Age,忽略 FirstName 和 LastName
(_, _, int age) = person;// 或者,如果你只關心 LastName
(string _, string lastName, _) = person; // 第一個參數也用棄元Console.WriteLine(age); // 輸出:40
Console.WriteLine(lastName); // 輸出:Banner

3. 進階使用

3.1 為自定義類型添加解構能力

要使你的自定義類或結構體能夠被解構,你需要為其定義一個或多個 Deconstruct方法。

規則

  1. 方法名必須為 Deconstruct
  2. 方法必須是 public void
  3. 所有參數都必須使用 out 修飾符
  4. 參數的順序和數量決定了你解構時變量的順序和數量
1. 為 Person 類實現解構
public class Person
{public string FirstName { get; set; }public string LastName { get; set; }public int Age { get; set; }// 構造函數public Person(string firstName, string lastName, int age){FirstName = firstName;LastName = lastName;Age = age;}// 實現 Deconstruct 方法// 此方法允許將 Person 解構成 (firstName, lastName, age)public void Deconstruct(out string firstName, out string lastName, out int age){firstName = FirstName;lastName = LastName;age = Age;}// 重載:提供另一種解構方式,例如只解構出fullName、agepublic void Deconstruct(out string fullName, out int age){fullName = $"{FirstName} {LastName}";age = Age;}
}
2 擴展方法解構

// 1. 定義靜態擴展類
public static class PersonExtensions
{// 2. 在擴展類中聲明 Deconstruct 擴展方法。注意:必須是靜態(static)且無返回值(void),所有要解構出的參數都使用 out 修飾符。public static void Deconstruct(this Person p,out string firstName,out string lastName,out int age){firstName = p.FirstName;lastName  = p.LastName;age       = p.Age;}// 3. 還可以再寫其他重載public static void Deconstruct(this Person p,out string fullName,out int age){fullName = $"{p.FirstName} {p.LastName}";age      = p.Age;}
}

3.2 與記錄(record) 的協同

錄類型(record)天然支持基于位置參數的解構功能。

record Person(string FirstName, string LastName);var (f, l) = new Person("Ada", "Lovelace");

3.3 與模式匹配的聯動(C# 8+)

從C# 8開始,解構功能與模式匹配語法深度集成,特別是在 switch 表達式中,可以直接對元組或可解構類型進行模式匹配。

例如:屬性模式(property pattern)與位置模式(positional pattern)的結合使用。編譯器會自動解構 Point 類型的坐標值,然后通過條件模式匹配進行判斷。

static string Quadrant(Point p) => p switch
{( > 0, > 0) => "第一象限",( < 0, > 0) => "第二象限",_           => "其他"
};

4. 限制與最佳實踐

  1. 命名一致性

    元組字段名與 Deconstruct 方法的 out 參數名無需強制一致,但保持命名一致性能顯著提升代碼的可讀性和可維護性。

  2. 可空性處理

    當類型中的字段可能為 null 時,應在 Deconstruct 方法內部進行必要的空值防御性檢查,并將對應的 out 參數類型標記為可空(如 out string? name)。

  3. 避免濫用

    解構雖方便,但過度使用會讓代碼意圖變得模糊。應僅在能“明顯提升可讀性”的場景(如同時獲取多個相關返回值)下使用,而非替代所有屬性訪問。

  4. out 參數的限制?

    在異步方法(標記為 async)中,不能使用 out 參數,因此也無法直接進行解構操作。

    常見的解決方法是先在同步代碼中解構,將結果存入變量,再在異步方法中使用這些變量

    // 異步方法中無法直接解構:
    // var (name, age) = await GetPersonAsync(); // 錯誤// 解決方案:先同步獲取對象,再解構
    var person = await GetPersonAsync();
    var (name, age) = person; // 正確
    

5. 總結

C# 的解構功能將對象(或元組)分解到一組獨立的變量中,簡化了從元組或對象中提取多個值的操作:

  • 元組析構:直接解包元組元素,支持類型推斷和棄元_
  • 自定義類型析構:通過實現 Deconstruct 方法支持解構;
  • 擴展方法析構:為現有類型添加析構能力;
  • 集成使用:與元組、模式匹配、Record集成、適合變量交換及多返回值方法的調用場景。
  • 適合場景:適用于數據模型、DTO、坐標、元組等主要存儲數據的簡單對象。
Deconstruct
├── 內建:ValueTuple / record 位置參數
├── 自定義:實例方法 或 擴展方法 void Deconstruct(out T1, out T2, ...)
└── 語法形式:├─ var (a, b) = obj;├─ (int a, _) = obj;└─ switch 模式 (x, y)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/920787.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/920787.shtml
英文地址,請注明出處:http://en.pswp.cn/news/920787.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

R 語言 ComplexUpset 包實戰:替代 Venn 圖的高級集合可視化方案

摘要 在生物信息學、數據挖掘等領域的集合分析中,傳統 Venn 圖在多維度數據展示時存在信息擁擠、可讀性差等問題。本文基于 R 語言的 ComplexUpset 包,以基因表達研究為場景,從包安裝、數據準備到可視化實現,完整演示如何制作正刊級別的集合交集圖,解決多條件下差異基因(…

?導游|基于SprinBoot+vue的在線預約導游系統

在線預約導游系統 基于SprinBootvue的在線預約導游系統 一、前言 二、系統設計 三、系統功能設計 前臺功能實現 后臺功能實現 管理員模塊實現 導游模塊實現 用戶模塊實現 四、數據庫設計 五、核心代碼 六、論文參考 七、最新計算機畢設選題推薦 八、源碼獲取&am…

SQL server 異常 出現錯誤 824

2025-08-27 01:36:37,324 ERROR c.z.i.w.DatabaseUtils [Scheduled-7] Error executeStoredProcedure SQL script: sp_RefreshDWDByDateFive警告: 在 08 27 2025 1:36AM 出現錯誤 824。請記錄該錯誤和時間&#xff0c;并與您的系統管理員聯系。 2025-08-27 01:36:37,332 ERROR …

制造業生產線連貫性動作識別系統開發

制造業生產線連貫性動作識別系統開發 第一部分&#xff1a;項目概述與理論基礎 1.1 項目背景與意義 在現代智能制造環境中&#xff0c;盡管自動化程度不斷提高&#xff0c;但人工操作仍然在復雜裝配任務中扮演著不可替代的角色。研究表明&#xff0c;人機協作被視為打破傳統人機…

什么是Jmeter? Jmeter工作原理是什么?

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 第一篇 什么是 JMeter&#xff1f;JMeter 工作原理 1.1 什么是 JMeter Apache JMeter 是 Apache 組織開發的基于 Java 的壓力測試工具。用于對軟件做壓力測試&a…

Linux網絡基礎1(一)之計算機網絡背景

文章目錄計算機網絡背景網絡發展認識 "協議"高小琴例子方言例子計算機網絡背景 網絡發展 獨立模式: 計算機之間相互獨立; 網絡互聯: 多臺計算機連接在一起, 完成數據共享; 局域網LAN: 計算機數量更多了, 通過交換機和路由器連接在一起; 廣域網WAN: 將遠隔千里的計算…

如何在數學建模賽中實現模型創新?

模型創新性在國賽數學建模中&#xff0c;完備性是論文的基本要求&#xff0c;而創新性則是決定論文能否脫穎而出的關鍵因素。所謂創新&#xff0c;并不僅僅指提出完全新穎的數學理論&#xff0c;而是能夠在已有方法的基礎上&#xff0c;通過新的問題切入點、假設修正、模型優化…

【重磅發布】flutter_chen_updater-版本升級更新

Flutter Chen Updater 一個功能強大的Flutter應用內更新插件&#xff0c;支持Android APK自動下載、安裝和iOS跳轉App Store。 ? 特性 ? 跨平臺支持: Android APK自動更新&#xff0c;iOS跳轉App Store? 智能下載: 支持斷點續傳、文件校驗、多重備用方案? 權限管理: 自動處…

docker 1分鐘 快速搭建 redis 哨兵集群

使用 docker-compose 1 分鐘搭建好 1主2從3哨兵的 redis 哨兵集群 目錄結構 redis-sentinel-cluster ├── check_redis.sh ├── docker-compose.yml ├── redis │ └── redis.conf ├── sentinel │ └── sentinel.confdocker-compose.yml 配置 version: 3…

Git與DevOps實戰:從版本控制到自動化部署

一、版本控制1.什么是版本控制&#xff1f;版本控制用于高效追蹤和管理項目開發中的代碼、配置及文檔變更歷史&#xff0c;確保團隊成員始終使用正確版本&#xff0c;并支持版本回溯、差異比較和文件恢復。它能帶來以下優勢&#xff1a;通過歷史記錄保障數據安全與完整性&#…

大模型——利用RAG構建智能問答平臺實戰

利用RAG構建智能問答平臺實戰 目前公司的智能問答平臺利用RAG技術構建,現給大家分享下通RAG技術構建智能問平臺的具體流程和原理。 一、什么是RAG RAG是檢索增強生成技術(Retrieval-Augmented Generation),目前是構建智能問答的重要技術。RAG相比傳統的檢索可以可以減少…

flume事務機制詳解:保障數據可靠性的核心邏輯

flume事務機制詳解&#xff1a;保障數據可靠性的核心邏輯 在數據采集過程中&#xff0c;“不丟數據、不重數據” 是核心需求。Flume 之所以能在分布式環境下保證數據可靠性&#xff0c;關鍵在于其內置的事務機制。Flume 通過在 “Source → Channel” 和 “Channel → Sink” …

第四十九天(springboot模版注入ThymeleafFreemarkerVelocity)

開發框架-SpringBoot 參考&#xff1a;Spring Boot 中文文檔 新建一個spring Boot 項目&#xff0c;修改服務器url為 aliyun.com 不然沒有與jdk8版本對應的java 選擇一個spring web 庫&#xff0c;點擊創建即可 來到這個頁面點擊運行 啟動的是8080端口&#xff0c;用127.0.0.1…

Spring MVC 九大組件源碼深度剖析(六):HandlerExceptionResolver - 異常處理的藝術

文章目錄一、異常處理的核心價值二、核心接口設計三、四大內置實現類源碼解析1. ExceptionHandlerExceptionResolver&#xff08;現代異常處理核心&#xff09;2. ResponseStatusExceptionResolver&#xff08;HTTP狀態碼處理&#xff09;3. DefaultHandlerExceptionResolver&a…

MCP(Model Context Protocol,模型上下文協議)介紹

1. 背景 隨著大語言模型&#xff08;LLM, Large Language Model&#xff09;的應用越來越廣泛&#xff0c;一個核心問題逐漸凸顯&#xff1a; 模型在對話或推理時&#xff0c;往往只能依賴有限上下文窗口。外部工具、知識庫、應用接口如何統一接入模型&#xff0c;缺乏標準協議…

synchronized的鎖對象 和 wait,notify的調用者之間的關系

誰調用了wait和notify方法&#xff0c;會決定這兩個方法的控制范圍嗎&#xff1f;你的問題非常深入&#xff0c;涉及到 wait() 和 notify() 方法的控制范圍和作用域。讓我們詳細分析一下&#xff1a;? 核心概念&#xff1a;控制范圍由“鎖對象”決定wait() 和 notify() 的控制…

【技術教程】如何將文檔編輯器集成到用 .Net 編寫的網絡應用程序中

在現代網絡應用中&#xff0c;?富文本編輯能力已成為內容管理系統的核心需求。對于 .NET 開發者而言&#xff0c;選擇適合的編輯器并高效集成&#xff0c;是構建企業級應用的關鍵一步&#xff0c;可讓項目管理、 CRM 或定制化系統具備原生辦公能力&#xff0c;消除頻繁切換應用…

【大模型記憶-Mem0詳解-1】概述

目的和能力 Mem0 通過提供以下功能將無狀態 AI 應用程序轉換為有狀態、支持內存的系統&#xff1a; 持久記憶 &#xff1a;跨會話長期保留用戶偏好、對話歷史記錄和上下文信息多級內存 &#xff1a;支持具有自適應個性化的用戶級、會話級和代理級內存智能提取 &#xff1a;基于…

2024年山東省信息學小學組(CSP-X)第一輪題解

2024年山東省信息學小學組(CSP-X)第一輪題解 原題下載 單項選擇題 閱讀程序 閱讀程序 #1 判斷題 閱讀程序 #2 判斷題 單選題 閱讀程序 #3 判斷題 單選題 完善程序 消滅怪獸 位運算操作 原題下載 CSP-X2024小學組(山東)第一輪試題以及答案 單項選擇題 共 15 題,每題 2 分…

SW - 用裝配圖的方式組合多個子零件然后轉換成為零件,可維護性好

文章目錄SW - 用裝配圖的方式組合多個子零件然后轉換成為零件&#xff0c;可維護性好概述筆記例子將裝配圖另存為零件將零件圖中的多個實體組合為一個實體的特征備注ENDSW - 用裝配圖的方式組合多個子零件然后轉換成為零件&#xff0c;可維護性好 概述 以前畫機械零件&#x…