[譯]C# 7系列,Part 1: Value Tuples

来源:https://www.cnblogs.com/wenhx/archive/2019/12/01/c-7-series-part-1-value-tuples.html
-Advertisement-
Play Games

Mark Zhou寫了很不錯的一系列介紹C# 7的文章,雖然是2年多年前發佈的,不過對於不熟悉C# 7特性的同學來說,仍然有很高的閱讀價值。 原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/26/c-7-series-part-1-value-t ...


Mark Zhou寫了很不錯的一系列介紹C# 7的文章,雖然是2年多年前發佈的,不過對於不熟悉C# 7特性的同學來說,仍然有很高的閱讀價值。

原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/26/c-7-series-part-1-value-tuples/

 

譯文:

從今天開始,我將開始一個新的C# 7系列文章,介紹C# 7+的新語言特性。請註意,我說的不是C# 7.0,我說的是C# 7+,因為將會有一些小的版本(比如7.1、7.2)逐步引入新的特性(感謝Roslyn!),比如async Main和default literals。

Tuples

類System.Tuple提供了一種類型來表示類似屬性包的鍵值對。當你想用一種數據結構來保存一個帶有屬性(元素)的對象,但又不想創建一個單獨的類型的時候,你可以使用它。下麵的代碼展示瞭如何用它作為一個方法的返回值,這個返回值包含了學生姓名和年齡。

public Tuple<string, int> GetStudentInfo(string id)
{     
    // Search by ID and find the student.
    return new Tuple<string, int>("Annie", 25);
}

可以看到,我返回了一個Tuple<string,int>的實例對象,它的第一個參數是name,第二個參數是age。之後,我們在代碼中調用這個方法,像這樣:

public void Test()
{     
    Tuple<string, int> info = GetStudentInfo("100-000-1000");
    Console.WriteLine($"Name: {info.Item1}, Age: {info.Item2}");
}

你可以通過引用Item1和Item2來訪問name和age。

Tuple類有一些明顯的問題:

  • 您需要使用ItemX這樣的形式來訪問屬性,這樣的屬性名可能對調用者來說沒有什麼含義,如果我們可以使用類似info.Nameinfo.Age這樣的形式來訪問會比info.Item1info.Item2更好
  • 最多只能有8個屬性。如果需要更多,最後一個類型參數必須是另一個元組。這使得語法非常難以理解。
  • Tuple是一種引用類型,不像其他基本類型(它們是大多數值類型),它分配在堆上,對於CPU密集型操作來說,它可能需要太多的對象創建/分配。

Value Tuples

C# 7.0引入了ValueTuple結構,它是Tuple對象的值類型表示。C#語言團隊為這個值元組類型做了很多不錯的事情,包括新的語法和許多特性(比如解構)。

下麵是使用Value Tuples的重寫版本,請註意,如果在你的項目中不能用ValueTuple類型,那你必須通過NuGet下載System.ValueTuple 4.3.0 NuGet包到你的項目。如果您使用的是.Net Framework 4.7或更高版本,或者.Net Standard Library 2.0或更高版本,你什麼也不用做,ValueTuple已經包含在內了。

public (string, int) GetStudentInfo(string id)
{
    // Search by ID and find the student. 
    return ("Annie", 25);
}
 
public void Test()
{ 
    (string, int) info = GetStudentInfo("100-000-1000"); 
    Console.WriteLine($"Name: {info.Item1}, Age: {info.Item2}");
}

通過使用語法(),上面的代碼得到了極大的簡化。 
您甚至可以為ValueTuple中的每個元素指定一個名稱,如下所示:

public (string name, int age) GetStudentInfo(string id)
{
    // Search by ID and find the student.
    return (name: "Annie", age: 25);
}
 
public void Test()
{
    (string name, int age) info = GetStudentInfo("100-000-1000"); 
    Console.WriteLine($"Name: {info.name}, Age: {info.age}");
}

帥!現在你的元組對象中的元素有了好的元數據,那麼你就不需要來回檢查確認返回/訪問元素的順序是正確的了。

當您使用值元組時,Visual Studio IDE會給您提示。

Value Tuple 解構

您可以從值元組對象中解構元素,並訪問局部變數。

// 解構使用 var (x, y) 語法,
// 或者 (var x, var y) 語法。
var (name, age) = GetStudentInfo("100-000-1000");
// 現在你有兩個局部變數:name and age.
Console.WriteLine($"Name: {name}, Age: {age}");

如果只關心某些元素而不是所有元素,可以使用_關鍵字忽略局部變數。

var (name, _) = GetStudentInfo("100-000-1000");
// 現在你只有一個局部變數:name,值age被忽略了。
Console.WriteLine($"Name: {name}");

從Value Tuples到Tuples

類型System.TupleSystem.ValueTuple提供了一些擴展方法來幫助它們之間相互轉換。

var valueTuple = (id: 1, name: "Annie", age: 25, dob: DateTime.Parse("1/1/1993"));
var tuple = valueTuple.ToTuple();

 

結論

ValueTuple使C#語言更現代,更易於使用簡化的語法。它解決了許多Tuple的問題:

  • 值元組對象具有第一類語法支持,它簡化了使用元組元素的代碼。
  • 您可以用一個名稱與值元組的元素相關聯,從而獲得一定程度的設計階段和編譯器階段的代碼驗證。
    請註意,與元組元素相關聯的名字不是一個運行時的元數據,即在運行時的實例值元組中不存在這樣一個名稱的屬性/欄位,屬性的名稱仍Item1、Item2等等,所有的元素名稱僅存在設計和編譯階段。
  • 你現在可以通過使用解構和_關鍵字靈活地訪問所有元組元素,或者其中的一部分。
  • 值元組類型是值類型,沒有繼承或其他特性,這意味著值元組具有更好的性能。

由於值元組元素的名稱不是運行時的,所以在使用一些類庫(如Newtonsoft)進行序列化時,必須小心使用元組類型。除非你更新過支持新元數據(TupleElementNameAttribute等)的類庫,否則你會遇到bug。


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

-Advertisement-
Play Games
更多相關文章
  • [TOC] 1. 概述 本來是不想寫Paramiko的,因為我覺得之前的一篇關於Netmiko模塊更適合網工,後來發現paramiko有包含SFTP功能,所以還是有必要來講講,畢竟我們在設備上是要經常下載配置、上傳版本/升級版本用的,而且SFTP比FTP、TFTP更安全。 所以, 你也不用藉助其他工 ...
  • 01 實現自定義的可變長數組類型 假設我們要實現一個會自動擴展的數組,要實現什麼函數呢?先從下麵的main函數給出的實現,看看有什麼函數是需要我們實現的。 輸出結果: 要實現的方式,要做哪些事情呢?我先列一下: 要用動態分配的記憶體來存放數組元素,需要一個指針成員變數 重載賦值=運算符 重載[]運算符 ...
  • 01 賦值運算符重載的需求 有時候希望賦值運算符兩邊的類型可以不匹配,比如:把一個 int 類型變數賦值給一個Complex(複數)對象,或把一個 char 類型的字元串賦值給一個字元串對象,此時就需要重載賦值運算符‘=’。 需要註意的是:賦值運算符 只能重載為成員函數。 02 賦值運算符重載的例子 ...
  • 01 運算符重載的需求 C++ 預定義的運算符,只能用於基本數據類型的運算:整型、實型、字元型、邏輯型等等,且不能用於對象的運算。但是我們有時候又很需要在對象之間能用運算符,那麼這時我們就要 重載運算符 ,使得運算符能用於對象之間的運算。 比如,在數學上,兩個複數可以直接進行+、 等運算,但在C++ ...
  • 本系列將和大家分享下ASP.NET Core Web 應用程式的一些基礎知識,本章主要簡單介紹下在ASP.NET Core中如何使用AutoMapper進行實體映射。 ...
  • 作為開發人員,您始終需要處理應用程式配置數據。常見的示例是INI 文件,XML文件, .NET配置文件(也稱為“ .config”),Windows註冊表和命令行(argv)參數。配置文件的優點是它們載入速度快,不占用大量空間且易於編輯。Nini是一個功能強大的 .NET配置庫,旨在幫助快速構建高度... ...
  • 探究 C 中的 char 、 string(一) [TOC] 1. System.Char 字元 char 是 System.Char 的別名。 System.Char 占兩個位元組,16個二進位位。 System.Char 用來表示、存儲一個 Unicode 字元。 System.Char 的表示範 ...
  • 今天介紹一個開源的C# WPF開源控制項庫,非常漂亮,重點是開源哦 WPF做桌面開發是很有優勢的,除了微軟自帶的控制項外,還有很多第三方的控制項庫,比如收費的Dev Express For WPF、Telerik For WPF等,及Github上開源免費的控制項庫如MaterialDesignInXAML ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...