C# Tuple元组用法详解(附带实例)
元组(Tuple)是 C# 4.0 以后的新功能,是引用数据类型。后来在 C# 7.0 提供改良版本,称为 ValueTuple,是值数据类型。
对于程序设计师而言,其实可以忽略是 C# 4.0 的 Tuple 还是 C# 7.0 以后的版本 ValueTuple,因为在 2023 年的今天,对于 C# 10 和 11 或未来更高阶版本,这两个版本都可以执行。
下列是 C# 4.0 时使用 Tuple 声明含 3 个元素的元组,重点是使用“<>”尖括号声明元组每个元素的数据类型。
使用 var 关键词可以简化声明方式,Tuple 使用 Create() 创建元组内容:
元组在 C# 4.0 时期使用 Tuple.Create() 方法创建元组,在 C# 7.0 后可以简化声明如下:
注意,ValueTuple 关键词依旧可以用于声明元组,读者也可以使用下列方式声明元组:
【实例 1】使用 C# 4.0 方式声明元组 Tuple,然后输出。
【实例 2】使用 C# 7.0 方式声明元组 Tuple,然后输出。
上述两个程序笔者分别使用了 C# 4.0 和 7.0 版本创建元组,在后文则倾向于使用 C# 7.0 方式声明和创建元组。
元组有提供 Rest 属性,可以用小括号列出第 8(含)个以后的元素。
【实例 3】使用 Rest 属性输出第 8 个及以后的元素,这个程序也测试了 Item8、Item9 和 Item10 属性。
【实例 3】使用 Rest.Item1、Rest.Item2 等,输出嵌套的元组内容。
【实例 4】创建嵌套元组,同时输出做测试。
【实例 5】省略 Tuple.Create() 方法创建嵌套元组。
也可以使用下列方式为元素命名:
【实例 6】设置元素名称的应用。
也可以先设定元素内容给变量,然后将此变量设定给元组。
【实例 7】设定变量给元组的应用。
也可以直接在元组内将值设定给变量,然后解析元组变量,这个动作称为元组解构。例如:
【实例 8】元组比较的实例。
对于程序设计师而言,其实可以忽略是 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
【实例 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 岁是 程序员