from:https://mp.weixin.qq.com/s/VF9XAHxgA7d22sMdZ-ilpQ
解構是將一個對象分割成若干部分並將其存儲到新的變量中。在 C# 中,解構可以方便地一次性將一個對象的多個成員的值存儲到多個變量中。
1解構元組
元組為方法返回多個值提供了便捷,無需創建額外的類型來承載返回的值。例如,下面這個方法使用元組返回兩個值:
public static (string, string, int) GetPerson()
{
var firstName = "Liam";
var lastName = "Wang";
var age = 18;
return (firstName, lastName, age);
}
對於檢索這個方法返回元組的各成員,如果不使用解構,我們可能需要這樣寫:
var person = GetPerson();
var firstName = person.Item1;
var lastName = person.Item2;
var age = person.Item3;
使用解構,則可以一次性將元組的各成員分別賦值給不同的變量,可以這樣寫:
(string firstName, string lastName, int age) = GetPerson();
// firstName = "Liam"
// lastName = "Wang"
// age = 18
也可以使用 var 自動推斷各個變量的類型:
var (firstName, lastName, age) = GetPerson();
// firstName = "Liam"
// lastName = "Wang"
// age = 18
元組的解構是基於成員的位置順序來的,即將 Item1 賦給第一上變量,將 Item2 賦給第二個變量……。
但是,一旦你使用解構檢索元組,你就必須處理它的各個成員。我們可以使用 棄元(_)來處理我們不關心的成員,只獲取元組中的我們需要的部分成員。例如:
var (firstName, _, _) = GetPerson();
// firstName = "Liam"
2解構類
我們也可以對類進行解構,並像對元組那樣訪問特定的字段。但為了實現這個目的,我們需要給類添加一個 Deconstruct() 方法,例如:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public void Deconstruct(out string firstName, out string lastName, out int age)
{
firstName = FirstName;
lastName = LastName;
age = Age;
}
}
然后可以和元組對象一樣使用解構:
var person = new Person { FirstName = "Liam", LastName = "Liam", Age = 18 };
var (firstName, lastName, age) = person;
或只關心部分成員:
...
var (firstName, _, _) = person;
Deconstruct() 方法允許重載,比如:
...
public void Deconstruct(out string firstName, out string lastName) =>
(firstName, lastName) = (FirstName, LastName);
public void Deconstruct(out string firstName, out string lastName, out int age) =>
(firstName, lastName, age) = (FirstName, LastName, Age);
它會根據解構時的聲明的變量數調用對應的 Deconstruct() 方法。
...
var (firstName, lastName) = person;
var (firstName, lastName, age) = person;
也可以通過靜態擴展方法的方式給類的實例添加 Deconstruct() 方法,比如:
public static class PersonExtensions
{
public static void Deconstruct(this Person person,
out string firstName, out string lastName, out int age)
{
firstName = person.FirstName;
lastName = person.LastName;
age = person.Age;
}
}
3解構記錄
C# 9 的記錄(Record)類型和元組一樣,可以根據成員順序直接解構。例如:
record Person(string FirstName, string LastName, int age);
static void Main(string[] args)
{
var person = new Person("Liam", "Wang", 18);
var (firstName, lastName, age) = person;
}
// firstName = "Liam"
// lastName = "Wang"
// age = 18
記錄類型既可以和類一樣有具名成員,也可以和元組一樣有基於成員順序的可解構特性,不需要單獨定義 Deconstruct() 方法。