C# 元组
最后修改于 2024 年 1 月 26 日
在本文中,我们将展示如何在 C# 中使用元组类型。
元组 是未命名但有序的值的分组。 这些值可以是不同的类型。 元组可以是引用类型(由 System.Tuple
支持)或值类型(由 System.ValueTuple
支持)。
自 C# 7 以来,元组已成为语言语法的一部分。 在本文中,我们将重点关注较新的语法。 新语法使用圆括号来定义和使用元组。
C# 元组简单示例
在以下示例中,我们使用旧方法和新方法创建一个新元组。
var u1 = Tuple.Create("John", "Done", "gardener"); Console.WriteLine($"{u1.Item1} {u1.Item2} is a {u1.Item3}"); var u2 = ("Roger", "Roe", "driver"); Console.WriteLine($"{u2.Item1} {u2.Item2} is a {u2.Item3}");
我们创建两个元组并将它们的内容打印到控制台。
var u1 = Tuple.Create("John", "Done", "gardener"); Console.WriteLine($"{u1.Item1} {u1.Item2} is a {u1.Item3}");
这是创建元组的旧方法。 创建 System.Tuple
的新实例。 元组的成员通过 ItemN 成员访问。 此元组是引用类型。
var u2 = ("Roger", "Roe", "driver"); Console.WriteLine($"{u2.Item1} {u2.Item2} is a {u2.Item3}");
这是创建元组的最新方法。 此元组是值类型。 我们使用 Item1
、Item2
和 Item3
访问元组字段;但是,可以命名我们的字段。
$ dotnet run John Done is a gardener Roger Roe is a driver
C# 元组字段名称
我们可以命名我们的元组字段。
var u1 = (Name: "John Doe", Age: 34); Console.WriteLine($"{u1.Name} is {u1.Age} years old"); (string Name, int Age) u2 = ("Roger Roe", 55); Console.WriteLine($"{u2.Name} is {u2.Age} years old"); var name = "Jane Doe"; var age = 26; var u3 = (name, age); Console.WriteLine($"{u3.name} is {u3.age} years old");
该示例显示了命名元组字段的三种不同方法。
var u1 = (Name: "John Doe", Age: 34);
字段名称与它的值用冒号字符分隔。 字段用逗号分隔。
Console.WriteLine($"{u1.Name} is {u1.Age} years old");
这里我们通过它们的名称引用元组字段。
(string Name, int Age) u2 = ("Roger Roe", 55);
当我们将一个元组分配给另一个元组时,我们在变量名称之前的圆括号内指定名称和类型。
var name = "Jane Doe"; var age = 26; var u3 = (name, age);
可以从现有变量创建元组。 编译器推断字段的类型。
C# 元组交换值
使用元组,我们可以轻松地交换两个变量的值。
var (x, y) = (11, 2); Console.WriteLine($"x: {x}"); Console.WriteLine($"y: {y}"); (y, x) = (x, y); Console.WriteLine($"x: {x}"); Console.WriteLine($"y: {y}");
我们定义并初始化两个变量 x
和 y
。 稍后,我们在一行中交换它们的值。
(y, x) = (x, y);
元组允许我们在一行中轻松地交换值。
$ dotnet run x: 11 y: 2 x: 2 y: 11
C# 元组解构
我们可以通过一个操作解包元组中的所有项。 这称为元组解构。
var (name1, age1) = ("John Doe", 34); Console.WriteLine($"{name1} is {age1} years old"); (string name2, int age2) = ("Roger Roe", 55); Console.WriteLine($"{name2} is {age2} years old"); string name3; int age3; (name3, age3) = ("Jane Doe", 26); Console.WriteLine($"{name3} is {age3} years old");
该示例展示了如何解构元组。
var (name1, age1) = ("John Doe", 34);
元组字段值存储在 name1
和 age1
变量中。 我们一步完成变量定义和赋值。
(string name2, int age2) = ("Roger Roe", 55);
这里我们显式指定变量类型。
string name3; int age3; (name3, age3) = ("Jane Doe", 26);
C# 嵌套元组
可以将元组嵌套到其他元组中。
var data = ((1, 2, 3), (3, 4, 5), (6, 7, 8)); Console.WriteLine(data); Console.WriteLine(data.Item1); Console.WriteLine(data.Item2); Console.WriteLine(data.Item1); Console.WriteLine(data.Item1.Item1); Console.WriteLine(data.Item2.Item3);
在该示例中,我们有一个元组,其中包含三个由三个值组成的嵌套元组。
Console.WriteLine(data.Item1);
在这里我们得到第一个嵌套元组:(1, 2, 3)
。
Console.WriteLine(data.Item1.Item1); Console.WriteLine(data.Item2.Item3);
在这里我们获得第一个嵌套元组的第一个和第三个元素。
$ dotnet run ((1, 2, 3), (3, 4, 5), (6, 7, 8)) (1, 2, 3) (3, 4, 5) (1, 2, 3) 1 5
C# 元组作为函数参数
元组可以是函数参数。
ShowInfo(("John", "Doe", "programmer")); ShowInfo(("Roger", "Roe", "driver")); ShowInfo(("Jane", "Doe", "teacher")); void ShowInfo((string FirstName, string LastName, string Occupation) u) { Console.WriteLine($"{u.FirstName} {u.LastName} is a {u.Occupation}"); }
在该示例中,我们将元组传递给 ShowInfo
函数,该函数从其字段构建并打印消息。
C# 元组作为返回值
可以从函数返回元组。
var user = GetUser(); Console.WriteLine($"{user.FirstName} {user.LastName} is a {user.Occupation}"); (string FirstName, string LastName, string Occupation) GetUser() { return ("John", "Doe", "programmer"); }
GetUser
的返回类型是一个具有三个字段的元组。
C# 元组 & 模式匹配
模式是一种语法形式,可用于表达要与传入数据进行比较的数据的形状。 元组是可以用于模式匹配的模式之一。
var rand = new Random(); List<string> opts = ["rock", "paper", "scissors"]; string p1 = opts[rand.Next(opts.Count)]; string p2 = opts[rand.Next(opts.Count)]; Console.WriteLine($"player 1 has {p1}, player 2 has {p2}"); string res = RockPaperScissors(p1, p2); Console.WriteLine(res); string RockPaperScissors(string player1, string player2) => (player1, player2) switch { ("rock", "paper") => "Rock is covered by paper. Player 2 wins", ("rock", "scissors") => "Rock breaks scissors. Player 1 wins.", ("paper", "rock") => "Paper covers rock. Player 1 wins.", ("paper", "scissors") => "Paper is cut by scissors. Player 2 wins.", ("scissors", "rock") => "Scissors are broken by rock. Player 2 wins.", ("scissors", "paper") => "Scissors cut paper. Player 1 wins.", (_, _) => "tie" };
这是一个简单的石头剪刀布游戏框架。
string RockPaperScissors(string player1, string player2) => (player1, player2) switch { ("rock", "paper") => "Rock is covered by paper. Player 2 wins", ("rock", "scissors") => "Rock breaks scissors. Player 1 wins.", ("paper", "rock") => "Paper covers rock. Player 1 wins.", ("paper", "scissors") => "Paper is cut by scissors. Player 2 wins.", ("scissors", "rock") => "Scissors are broken by rock. Player 2 wins.", ("scissors", "paper") => "Scissors cut paper. Player 1 wins.", (_, _) => "tie" };
我们在 switch 表达式中使用元组模式。 元组表示两个玩家的选择。 每个 switch 表达式分支代表游戏中可能出现的场景。
$ dotnet run player 1 has rock, player 2 has scissors Rock breaks scissors. Player 1 wins. $ dotnet run player 1 has paper, player 2 has rock Paper covers rock. Player 1 wins. $ dotnet run player 1 has scissors, player 2 has rock Scissors are broken by rock. Player 2 wins.
来源
在本文中,我们使用 C# 中的元组。
作者
列出所有 C# 教程。