首页 > 编程笔记 > C#笔记 阅读:7

C# Tuple元组用法详解(附带实例)

元组(Tuple)是 C# 4.0 以后的新功能,是引用数据类型。后来在 C# 7.0 提供改良版本,称为 ValueTuple,是值数据类型。

对于程序设计师而言,其实可以忽略是 C# 4.0 的 Tuple 还是 C# 7.0 以后的版本 ValueTuple,因为在 2023 年的今天,对于 C# 10 和 11 或未来更高阶版本,这两个版本都可以执行。

C#元组的声明

除了可以使用 Tuple 关键词,还可以使用我们熟悉的 var 来声明元组。

下列是 C# 4.0 时使用 Tuple 声明含 3 个元素的元组,重点是使用“<>”尖括号声明元组每个元素的数据类型。
Tuple<string, char, int> person = new Tuple<string, char, int>("Hung", 'M', 45);

使用 var 关键词可以简化声明方式,Tuple 使用 Create() 创建元组内容:
var person = Tuple.Create("Hung", 'M', 45);
注意,这个版本的 Tuple 元组限制最多可以有 8 个元素。

元组在 C# 4.0 时期使用 Tuple.Create() 方法创建元组,在 C# 7.0 后可以简化声明如下:
var person = ("Hung", 'M', 45);                   // 建议使用方式
或是使用下列方式声明:
(string, char, int) person = ("Hung", 'M', 45);

注意,ValueTuple 关键词依旧可以用于声明元组,读者也可以使用下列方式声明元组:
ValueTuple<string, char, int> person = ("Hung", 'M', 45);

C#存取元组元素内容

1) Item属性

元组创建后,未来可以使用 Item<elementNumber> 属性,如 Item1、Item2 等,取得属性内容。

【实例 1】使用 C# 4.0 方式声明元组 Tuple,然后输出。
Tuple<string, char, char, int> person1 =
    new Tuple<string, char, char, int>("Hung", 'M', 45);
Console.WriteLine(person1.Item1);
Console.WriteLine(person1.Item2);
Console.WriteLine(person1.Item3);

var person2 = Tuple.Create("Hung", 'M', 45); // C# 4.0 声明
Console.WriteLine(person2.Item1);
Console.WriteLine(person2.Item2);
Console.WriteLine(person2.Item3);
执行结果为:

Hung
M
45
Hung
M
45


【实例 2】使用 C# 7.0 方式声明元组 Tuple,然后输出。
(string, char, int) person1 = ("Hung", 'M', 45); // C# 7.0 声明
Console.WriteLine(person1.Item1);
Console.WriteLine(person1.Item2);
Console.WriteLine(person1.Item3);

var person2 = ("Hung", 'M', 45); // C# 7.0 声明
Console.WriteLine(person2.Item1);
Console.WriteLine(person2.Item2);
Console.WriteLine(person2.Item3);

ValueTuple<string, char, int> person3 = ("Hung", 'M', 45); // C# 7.0 声明
Console.WriteLine(person3.Item1);
Console.WriteLine(person3.Item2);
Console.WriteLine(person3.Item3);
执行结果,多一组输出,程序第 12 行是让读者知道可以使用此创建元组,一般建议使用第 2 行或第 7 行的方法即可,其他与实例 1 相同。

上述两个程序笔者分别使用了 C# 4.0 和 7.0 版本创建元组,在后文则倾向于使用 C# 7.0 方式声明和创建元组。

2) Rest属性

尽管从 C# 7.0 起已经解除了元组内只能含 8 个元素的限制,但是第 8 个以后的元素 C# 会用嵌套方式处理。

元组有提供 Rest 属性,可以用小括号列出第 8(含)个以后的元素。

【实例 3】使用 Rest 属性输出第 8 个及以后的元素,这个程序也测试了 Item8、Item9 和 Item10 属性。
var number = ("one", 2, 3, 4, 5, 6, "seven", 8, 9, 10);
Console.WriteLine(number.Item1);
Console.WriteLine(number.Item2);
Console.WriteLine(number.Item3);
Console.WriteLine(number.Item8);
Console.WriteLine(number.Item9);
Console.WriteLine(number.Item10);
Console.WriteLine(number.Rest);
执行结果为:
one
2
3
8
9
10
(8, 9, 10)
从上述执行结果可以看到 number.Rest 获得的输出是 (8, 9, 10),如果要输出嵌套的内容可以使用 Rest.Item1、Rest.Item2 等,输出嵌套的元组内容。

【实例 3】使用 Rest.Item1、Rest.Item2 等,输出嵌套的元组内容。
var number = ("one", 2, 3, 4, 5, 6, "seven", 8, 9, 10);
Console.WriteLine(number.Rest.Item1);
Console.WriteLine(number.Rest.Item2);
Console.WriteLine(number.Rest.Item3);
执行结果为:

8
9
10

C#创建嵌套元组

如果要创建嵌套元组,可以在小括号内部使用 Tuple.Create() 方法。

【实例 4】创建嵌套元组,同时输出做测试。
var number = ("one", 2, Tuple.Create(3, 4, 5, 6, "seven"), 8, 9, 10);
Console.WriteLine(number.Item1);
Console.WriteLine(number.Item2);
Console.WriteLine(number.Item3);
Console.WriteLine(number.Item3.Item1); // 3
Console.WriteLine(number.Item3.Item5); // seven
Console.WriteLine(number.Item4);
执行结果为:

one
2
(3, 4, 5, 6, seven)
3
seven
8

上述程序第 1 行笔者使用了 Tuple.Create() 方法创建嵌套元组内容,其实省略此方法,可以得到一样的结果。

【实例 5】省略 Tuple.Create() 方法创建嵌套元组。
var number = ("one", 2, (3, 4, 5, 6, "seven"), 8, 9, 10);
Console.WriteLine(number.Item1);
Console.WriteLine(number.Item2);
Console.WriteLine(number.Item3);
Console.WriteLine(number.Item3.Item1); // seven
Console.WriteLine(number.Item3.Item5); // seven
Console.WriteLine(number.Item4); // 8
执行结果与实例 4 相同。

C#元组设置元素名称

元组可以有元素名称,例如:
(string Name, char Gender, int age) person = ("Hung", 'M', 45);

也可以使用下列方式为元素命名:
var person = (Name:"Hung", Gender:'M', Age:45);

【实例 6】设置元素名称的应用。
(string Name, char Gender, int Age) person1 = ("Hung", 'M', 45);
Console.WriteLine(person1.Name);
Console.WriteLine(person1.Gender);
Console.WriteLine(person1.Age);

var person2 = (Name:"Hung", Gender:'M', Age:45);
Console.WriteLine(person2.Name);
Console.WriteLine(person2.Gender);
Console.WriteLine(person2.Age);
执行结果为:

Hung
M
45
Hung
M
45


也可以先设定元素内容给变量,然后将此变量设定给元组。

【实例 7】设定变量给元组的应用。
string title = "C#基础教程";
int price = 49;
var book = (Title:title, Price:price);
Console.WriteLine($"教程名:{book.Title}\t售价:{book.Price}");
执行结果为:

教程名:C#基础教程    售价:49


也可以直接在元组内将值设定给变量,然后解析元组变量,这个动作称为元组解构。例如:
var (Title, Price) = ("C#基础教程", 49);
Console.WriteLine((Title, Price));
Console.WriteLine($"{"教程名:{Title}\t售价:{Price}"});
执行结果为:

(教程名:C#基础教程, 售价:49)
教程名:C#基础教程    售价:49

C#元组赋值设定

元组可以通过等号执行赋值的设定。例如:
(int, double) x1 = (5, 3.14159);
(double First, double Second) x2 = (2.0, 1.0);
x2 = x1;
Console.WriteLine($"x2: {x2.First} 和 {x2.Second}");

(double A, double B) x3 = (5.5, 6.2);
x3 = x2;
Console.WriteLine($"x3: {x3.A} 和 {x3.B}");
执行结果为:

x2: 5 和 3.14159
x3: 5 和 3.14159

C#将==和!=符号用于元组比较

等号(==)或不等号(!=)也可以用于元组的比较,即使数据名称与类型不相同也可以比较,在比较时只看数据位置。

【实例 8】元组比较的实例。
(int a, byte b) x = (3, 6);
(long a, int b) y = (3, 6);
Console.WriteLine(x == y);    // True
Console.WriteLine(x != y);    // False

var x1 = (A: 9, B: 6);
var x2 = (B: 9, A: 6);
Console.WriteLine(x1 == x2);  // True
Console.WriteLine(x1 != x2);  // False
执行结果为:

True
False
True
False

C#把元组当作方法的参数进行传递

元组也可以作为方法的参数,例如:
void ShowInfo((string Name, int Age, string Occupation) u)
{
    Console.WriteLine($"{u.Name} 今年 {u.Age} 岁是 {u.Occupation}");
}
ShowInfo(("张三", 45, "程序员"));
ShowInfo(("李四", 30, "工程师"));
ShowInfo(("王五", 15, "学生"));
执行结果为:

张三 今年 45 岁是 程序员
李四 今年 30 岁是 工程师
王五 今年 15 岁是 学生

C#把元组当作方法的回传值

元组也可以作为方法的回传值,例如:
var u = GetData();
Console.WriteLine($"{u.Name} 今年 {u.Age} 岁是 {u.Occupation}");

(string Name, int Age, string Occupation) GetData()
{
    return ("张三", 45, "程序员");
}
执行结果为:

张三 今年 45 岁是 程序员

相关文章