C# - 值元组(ValueTuple)

本文关键字:ValueTuple 元组 | 更新日期: 2023-09-12 17:39:44

C# 7.0 (.NET Framework 4.7) 引入了 ValueTuple 结构,它是 Tuple 的值类型表示形式。

ValueTuple 仅在 .NET Framework 4.7 中可用。如果在项目中看不到 ValueTuple,则需要安装 ValueTuple。 (.NET Framework 4.7 或更高版本,或 .NET Standard Library 2.0 或更高版本已包含 ValueTuple。

若要安装 ValueTuple 包,请在解决方案资源管理器中右键单击该项目,然后选择"管理 NuGet 包"。这将打开 NuGet 包管理器。单击"浏览"选项卡,在搜索框中搜索"值元组",然后选择"System.ValueTuple"包,如下所示。

值元组初始化

创建和初始化ValueTuple很容易。 可以使用括号()创建和初始化它并指定其中的值。

var person = (1, "Bill", "Gates");
    
//equivalent Tuple
//var person = Tuple.Create(1, "Bill", "Gates");

还可以通过指定每个元素的类型来初始化ValueTuple,如下所示。

示例:ValueTuple
ValueTuple<int, string, string> person = (1, "Bill", "Gates");
person.Item1;  // returns 1
person.Item2;   // returns "Bill"
person.Item3;   // returns "Gates"

以下是为每个成员声明类型的简短方法。

示例:ValueTuple

(int, string, string) person = (1, "James", "Bond");
person.Item1;  // returns 1
person.Item2;   // returns "James"
person.Item3;   // returns "Bond"

请注意,我们在上面的元组初始化语句中没有使用var;相反,我们在括号内提供了每个成员值的类型。

元组至少需要两个值。以下不是元组。

var number = (1);  // int type, NOT a tuple
var numbers = (1,2); //valid tuple

Tuple不同,一个ValueTuple可以包含八个以上的值。

var numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); 

指定成员

我们可以为ValueTuple属性分配名称,而不是使用默认属性名称,如 Item1、Item2 等。

示例:ValueTuple 的命名成员
(int Id, string FirstName, string LastName) person = (1, "Bill", "Gates");
person.Id;   // returns 1
person.FirstName;  // returns "Bill"
person.LastName; // returns "Gates"

我们还可以在右侧为成员名称分配值,如下所示。

var person = (Id:1, FirstName:"Bill", LastName: "Gates");

请注意,我们可以在左侧或右侧提供会员名称,但不能在两侧提供成员名称。左侧优先于右侧。以下内容将忽略右侧的名称。

// PersonId, FName, LName will be ignored.
(int Id, string FirstName, string LastName) person = (PersonId:1, FName:"Bill", LName: "Gates");
// PersonId, FirstName, LastName will be ignored. It will have the default names: Item1, Item2, Item3.
(string, string, int) person = (PersonId:1, FName:"Bill", LName: "Gates");

我们还可以将变量赋值为成员值。

string firstName = "Bill", lastName = "Gates";
var per = (FirstName: firstName, LastName: lastName);

值元组作为参数

ValueType 也可以是方法的参数类型或返回类型。以下方法接受ValueTuple类型参数。

示例:作为参数
static void Main(string[] args)
{
    DisplayTuple((1, "Bill", "Gates"));
}
static void DisplayTuple((int, string, string) person)
{
    Console.WriteLine("{0}, {1}, {2}", person.Item1, person.Item2, person.Item3);
}

下面从该方法返回一个值元组。

示例:值元组作为返回类型
static void Main(string[] args)
{
    var person = GetPerson();
    Console.WriteLine("{0}, {1}, {2}", person.Item1, person.Item2, person.Item3);
}
static (int, string, string) GetPerson() 
{
    return (1, "Bill", "Gates");
}

还可以为从该方法返回的ValueTuple指定成员名称。

示例:值元组作为返回类型
static void Main(string[] args)
{
    var person = GetPerson();
    Console.WriteLine("{0}, {1}, {2}", person.Id, person.FirstName, person.LastName);
}
static (int Id, string FirstName, string LastName) GetPerson() 
{
    return (Id:1, FirstName: "Bill", LastName: "Gates");
}

Deconstruction

可以通过DeconstructionValueTuple来检索的各个成员。 Deconstruction声明语法将ValueTuple拆分为其部分,并将这些部分分别分配给新变量。

示例:Deconstruction ValueTuple
static void Main(string[] args)
{
    // change property names
    (int PersonId, string FName, string LName) = GetPerson();
}
static (int, string, string) GetPerson() 
{
    return (Id:1, FirstName: "Bill", LastName: "Gates");
}

我们也可以使用 var 代替显式数据类型名称。

示例:Deconstruction ValueTuple
static void Main(string[] args)
{
    // use var as datatype
    (var PersonId, var FName, var LName) = GetPerson();
}
static (int, string, string) GetPerson() 
{
    return (Id:1, FirstName: "Bill", LastName: "Gates");
}

ValueTuple还允许"丢弃"Deconstruction您不打算使用的成员。

// use discard _ for the unused member LName
(var id, var FName, _) = GetPerson();