Using Tuples (ValueTuple), available since C# 7.0, allows you to easily return multiple values from a method.
Previously, returning multiple values required using out arguments or defining specific classes or structures for the return value. By using tuples, you can write type-safe and highly readable code with a much concise syntax.
In this article, I will explain how to define tuples, how to receive values, and how to use variable deconstruction.
Implementation Example: Method Returning Product Name and Color
The following code is an example where the GetItem method returns two pieces of information, “Name” and “Color,” as a tuple, and the calling side receives them.
using System;
namespace TupleExample
{
class Program
{
static void Main(string[] args)
{
// Pattern 1: Receive as a tuple object
// Since element names are specified in the method definition,
// you can access them via .Name and .Color
var item = GetItem();
Console.WriteLine($"[Object] Product: {item.Name}, Color: {item.Color}");
// Pattern 2: Use Deconstruction
// Directly expand the tuple contents into individual variables
// Variable names do not have to match the method definition (Name, Color)
var (productName, productColor) = GetItem();
Console.WriteLine($"[Deconstruct] Product: {productName}, Color: {productColor}");
// Pattern 3: Discard unnecessary values
// If you only want to know the color, you can discard the name part with an underscore (_)
var (_, justColor) = GetItem();
Console.WriteLine($"[Discard] Color only: {justColor}");
}
// Define the return type as (string Name, string Color)
// This allows the caller to access elements using meaningful names
// instead of Item1, Item2
static (string Name, string Color) GetItem()
{
// Create and return a tuple literal (Value1, Value2)
return ("Banana", "Yellow");
}
}
}
Explanation and Key Points
1. Defining Return Values and Named Tuple Elements
While you can create a tuple simply by writing the return type as (string, string), it is recommended to name the elements, such as (string Name, string Color).
If there are no names, the caller must access elements using generic names like item.Item1 and item.Item2, which significantly reduces readability.
2. Deconstruction
By using the syntax var (name, color) = GetItem();, you can assign each element of the returned tuple to a local variable defined on the spot. This allows you to handle values intuitively without going through the tuple object itself.
3. Performance (ValueTuple)
Tuples in C# 7.0 and later are realized by the System.ValueTuple structure. Since this is a value type (struct), it places less load on garbage collection compared to the older System.Tuple class (which is a reference type and requires heap memory allocation), making it lightweight and efficient.
Summary
Tuples are a very powerful feature when you want to “return multiple values temporarily” from a method.
- Definition:
(Type Name, Type Name) MethodName() { ... } - Usage:
var result = MethodName();orvar (a, b) = MethodName(); - Benefits: No class definition required, lightweight, and type-safe.
While you should consider using classes if complex data structures are needed, you should actively use tuples when returning simple pairs of values.
