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

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

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。


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

更多相關文章
  • [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 ...
一周排行
  • 比如要拆分“呵呵呵90909086676喝喝999”,下麵當type=0返回的是中文字元串“呵呵呵,喝喝”,type=1返回的是數字字元串“90909086676,999”, private string GetStrings(string str,int type=0) { IList<strin ...
  • Swagger一個優秀的Api介面文檔生成工具。Swagger可以可以動態生成Api介面文檔,有效的降低前後端人員關於Api介面的溝通成本,促進項目高效開發。 1、使用NuGet安裝最新的包:Swashbuckle.AspNetCore。 2、編輯項目文件(NetCoreTemplate.Web.c ...
  • 2020 年 7 月 30 日, 由.NET基金會和微軟 將舉辦一個線上和為期一天的活動,包括 微軟 .NET 團隊的演講者以及社區的演講者。本次線上大會 專註.NET框架構建微服務,演講者分享構建和部署雲原生應用程式的最佳實踐、模式、提示和技巧。有關更多信息和隨時瞭解情況:https://focu... ...
  • #abp框架Excel導出——基於vue #1.技術棧 ##1.1 前端採用vue,官方提供 UI套件用的是iview ##1.2 後臺是abp——aspnetboilerplate 即abp v1,https://github.com/aspnetboilerplate/aspnetboilerp ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:碧茂大數據 PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取 input()輸入 Python提供了 input() 內置函數從標準輸入讀入一 ...
  • 從12年到20年,python以肉眼可見的趨勢超過了java,成為了當今It界人人皆知的編程語言。 python為什麼這麼火? 網路編程語言搜索指數 適合初學者 Python具有語法簡單、語句清晰的特點,這就讓初學者在學習階段可以把精力集中在編程對象和思維方法上。 大佬都在用 Google,YouT ...
  • 在社會上存在一種普遍的對培訓機構的學生一種歧視的現象,具體表現在,比如:當你去公司面試的時候,一旦你說了你是培訓機構出來的,那麼基本上你就涼了,那麼你瞞著不說,然後又通過了面試成功入職,但是以後一旦在公司被髮現有培訓經歷,可能會面臨被降薪,甚至被辭退,培訓機構出來的學生,在用人單位眼裡就是能力低下的 ...
  • from typing import List# 這道題看了大佬寫的代碼,經過自己的理解寫出來了。# 從最外圍的四周找有沒有為O的,如果有的話就進入深搜函數,然後深搜遍歷# 判斷上下左右的位置是否為Oclass Solution: def solve(self, board: List[List[s ...
  • import requests; import re; import os; # 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, li ...
  • import requests; import re; import os; import parsel; 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537. ...