What a tuple is
Some values belong together: a pet's name and age, a point's x and y. A tuple keeps a few such values in one variable without writing a class for them.
(string Name, int Age) pet = ("Rex", 4);
Console.WriteLine(pet.Name); // Rex
Console.WriteLine(pet.Age); // 4
Two different things use parentheses here. (string Name, int Age) is a type: it lists each part's type and, optionally, its name. ("Rex", 4) is a value: the parts in order, separated by commas. Read a part with a dot and its name.
Parts without names
If you leave the names out, the parts are called Item1, Item2 and so on. Named parts are easier to read, and a named tuple still has Item1 and Item2 underneath:
var plain = ("Rex", 4);
Console.WriteLine(plain.Item1 + " " + plain.Item2);
(string Name, int Age) pet = ("Rex", 4);
Console.WriteLine(pet.Item1 + " " + pet);
Rex 4
Rex (Rex, 4)
Printing a whole tuple shows its parts in parentheses, separated by a comma and a space.
Unpacking into variables
You can take a tuple apart in one line, with the new variables in the same order as the parts:
var (name, age) = pet;
Console.WriteLine(name + " " + age); // Rex 4
The names name and age are yours to choose. Only the order matters. If you only need one part, write a discard, var (_, years) = pet;.
Returning a tuple from a method
A method returns one value, but that value can be a tuple. This is the usual reason to reach for one: a method that has two answers.
public (int Hours, int Mins) SplitTime(int minutes) {
return (minutes / 60, minutes % 60);
}
The return type names the parts. return (a, b); builds the tuple. The caller can read SplitTime(135).Hours or unpack the result straight away: var (hours, mins) = SplitTime(135);.
The lesson's task, step by step
The starter code has SplitTime with an empty body and a pet tuple. Three things are missing.
- Return the tuple. Whole hours are
minutes / 60. Integer division throws the remainder away, so 135 / 60 is 2. The minutes left areminutes % 60, which is 15. - Unpack
pet. Writevar (name, age) = pet;below the firstConsole.WriteLine. The next line already usesnameandage. - Unpack the result of
SplitTime(135). A method call that returns a tuple unpacks exactly like a variable does.
The finished code:
class Solution {
public (int Hours, int Mins) SplitTime(int minutes) {
return (minutes / 60, minutes % 60);
}
public void MainFunction() {
(string Name, int Age) pet = ("Rex", 4);
Console.WriteLine(pet.Name);
var (name, age) = pet;
Console.WriteLine(name + " is " + age);
var (hours, mins) = SplitTime(135);
Console.WriteLine(name + " walked " + hours + " h " + mins + " min");
}
}
It prints:
Rex
Rex is 4
Rex walked 2 h 15 min
Another use: swapping two variables
Because a tuple is a value you can build on the spot, it gives C# a short way to swap two variables without a temporary one:
int x = 3;
int y = 5;
(x, y) = (y, x);
Console.WriteLine(x + " " + y); // 5 3
The right side builds the tuple (5, 3) first. Then the left side unpacks it into the existing variables. This time there is no var, because x and y already exist.
Traps
- Tuples are copied. Assigning a tuple to another variable copies its values. After
var a = (1, 2); var b = a; b.Item1 = 9;the variableais still(1, 2)andbis(9, 2). - Order matters, names don't. Unpacking matches parts by position.
var (age, name) = pet;compiles, becausevaraccepts any types, but it puts the name inageand the age inname. - Mixing up the type and the value.
(string Name, int Age)on the right side of=is not a value. Use("Rex", 4)there.
Key takeaways
- A tuple groups a few values:
("Rex", 4), with type(string Name, int Age). - Read parts with
pet.Name, or unpack them withvar (name, age) = pet;. - A method can return a tuple when it has more than one answer.
