← Back

C# Tuples — The “small return object” you should use more

2026-01-16 14:32 · 👁 12697

#c#

🚀 C# Tuples — The “small return object” you should use more

Tuples are one of those features that feel “too simple”… until you notice how often they remove boilerplate.

Instead of creating a class/record for every tiny return type, you can return multiple values cleanly, with great readability.

✅ When tuples shine
  • Returning 2–4 values from a method
  • Temporary grouping inside LINQ / transformations
  • Prototyping and internal APIs
  • Avoiding “one-off DTO classes”
❌ When tuples are a bad idea
  • Public APIs where a named type communicates meaning better
  • When values evolve (versioning becomes painful)
  • When you start passing tuples around everywhere (it becomes “anonymous domain modeling”)

1) Returning multiple values (the classic use)

var result = ValidateEmail("diego@site.com");

if (!result.ok)
    Console.WriteLine(result.message);

static (bool ok, string message) ValidateEmail(string email)
{
    if (string.IsNullOrWhiteSpace(email))
        return (false, "Email is required");

    if (!email.Contains('@'))
        return (false, "Invalid email format");

    return (true, "OK");
}

💡 Tip: Use named elements (ok, message) to avoid Item1, Item2.


2) Deconstruction makes it clean

var (ok, message) = ValidateEmail("x");

if (!ok)
    Console.WriteLine(message);

This is one of the biggest benefits: you get clarity without extra types.


3) Tuples in async code

public async Task<(User? user, bool found)> FindUserAsync(int id)
{
    var user = await _db.Users.FindAsync(id);
    return (user, user is not null);
}

var (user, found) = await FindUserAsync(10);

4) Tuples in LINQ (great for projections)

var stats = orders
    .GroupBy(o => o.CustomerId)
    .Select(g => (customerId: g.Key, total: g.Sum(x => x.Amount)))
    .OrderByDescending(x => x.total)
    .Take(10);

This is perfect when the result is local and short-lived.


5) ValueTuple vs Tuple (important difference)

  • System.Tuple<...> = reference type (heap allocation)
  • System.ValueTuple<...> (what C# tuple syntax uses) = struct (value type)

✅ Modern C# tuple syntax ((int a, int b)) uses ValueTuple.


Rules of thumb

✅ Use tuples for local, small, short-lived groupings
✅ Prefer named tuple elements
✅ If it crosses boundaries (public API / domain), use a record instead


🔥 Quick example: tuple vs record (boundary rule)

Tuple (good internally):
(int min, int max) GetRange() => (10, 20);
Record (better for public meaning):
public record Range(int Min, int Max);
public Range GetRange() => new(10, 20);

#CSharp #DotNet #SoftwareEngineering #CleanCode #Programming #DeveloperTips #LINQ #AsyncAwait #Performance #Architecture

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.