In this blog post, we will explore some cool things you can do with ValueTuple. Also, a short explanation of what ValueTuple is and how it works.
What is ValueTuple?#
ValueTuple in C# is a lightweight, mutable value type that enables grouping multiple values or related data together for various purposes, such as returning multiple values from a method, creating structured data, or combining values in dictionaries. It provides better performance compared to traditional reference types, as it doesn't require heap allocation.
(string FirstName, string LastName, int Age) person = ("Steven", "Giesel", 31);
person.FirstName; // returns "Steven"
person.LastName; // returns "Giesel"
person.Age; // returns 31
static (string FirstName, string LastName, int Age) GetPerson()
{
return ("Steven", "Giesel", 31);
}
Okay, that should be good enough. Let's start with some stuff we can do with that.
Swap two values#
Let's say we have two variables and want to swap their values. We can do that with ValueTuple in a single line of code.
int a = 1;
int b = 2;
// Here the swap
(a, b) = (b, a);
Easy IEquatable implementation#
ValueTuple can be leveraged to have an easy and readable implementation of IEquatable
public class Dimension : IEquatable<Dimension>
{
public Dimension(int width, int height)
=> (Width, Height) = (width, height);
public int Width { get; }
public int Height { get; }
public bool Equals(Dimension other)
=> (Width, Height) == (other?.Width, other?.Height);
public override bool Equals(object obj)
=> obj is Dimension dimension && Equals(dimension);
public override int GetHashCode()
=> (Width, Height).GetHashCode();
}
This also shows an easy way to compare two objects as well as receiving the hash code of the object.
Pattern matching with ValueTuple#
ValueTuples can be used in conjunction with pattern matching, enabling elegant and expressive code when working with different cases.
(string Name, int Age) person = ("Alice", 25);
string description = person switch
{
("Alice", >= 0 and < 13) => "Alice is a child.",
("Alice", >= 13 and < 20) => "Alice is a teenager.",
("Alice", >= 20 and < 65) => "Alice is an adult.",
("Alice", _) => "Alice is a senior.",
(_, >= 0 and < 13) => "The person is a child.",
(_, >= 13 and < 20) => "The person is a teenager.",
(_, >= 20 and < 65) => "The person is an adult.",
_ => "The person is a senior."
};
Deconstruction of custom types#
ValueTuples can be used to enable deconstruction of custom types, allowing your type to be broken down into separate variables easily.
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public void Deconstruct(out string name, out int age)
{
name = Name;
age = Age;
}
}
var student = new Student { Name = "John", Age = 21 };
// Deconstruct the Student object into separate variables
(string studentName, int studentAge) = student;
Conclusion#
There you got it - some ways where ValueTuple can be used to make your code more readable and easier to understand.
