Chapter 11 Composition Using Tuples
2 min read- Chapter 11 — Composition using tuples
- 11.1 Introduction to tuples
- 11.2 Tuple literals and tuple types
- 11.2.1 Syntax
- 11.2.2 Inferred element names (C# 7.1)
- 11.2.3 Tuples as bags of variables
- 11.3 Tuple types and conversions
- 11.3.6 Equality and inequality (C# 7.3)
- 11.4 Tuples in the CLR (`System.ValueTuple`)
- 11.4.1 `System.ValueTuple<...>`
- 11.4.5 Regular vs structural equality/ordering
- 11.4.7 Large tuples
- 11.5 Alternatives to tuples
- 11.6 Uses and recommendations
- 11.6.1 Nonpublic APIs and easily changed code
- 11.6.2 Local variables
- 11.6.3 Fields
- 11.6.4 Tuples and dynamic
Chapter 11 — Composition using tuples
Purpose of this chapter: become fluent with tuples as a lightweight composition tool, understand the difference between System.ValueTuple and System.Tuple, and know when not to use tuples (especially in public APIs).
11.1 Introduction to tuples
Tuples are “a bag of values” grouped together without defining a dedicated type.
Good for:
- Temporary grouping inside a method.
- Returning multiple values without out parameters.
Be cautious:
- Overusing tuples can create unclear code (unnamed semantics).
11.2 Tuple literals and tuple types
11.2.1 Syntax
var point = (x: 10, y: 20);
// point.x == 10
11.2.2 Inferred element names (C# 7.1)
Element names can often be inferred from variables/properties, reducing repetition.
11.2.3 Tuples as bags of variables
Guideline:
- Use meaningful element names when the tuple survives more than a few lines.
11.3 Tuple types and conversions
Tuples have types: (int x, int y) etc.
Key ideas:
- Conversions exist between tuple literals and tuple types when shapes match.
- Conversions between tuple types rely on element types and compatibility rules.
11.3.6 Equality and inequality (C# 7.3)
Tuples support value-like equality comparisons (element-wise) in many cases.
11.4 Tuples in the CLR (System.ValueTuple)
11.4.1 System.ValueTuple<...>
Modern C# tuples are backed by ValueTuple:
- Struct-based (value type)
- Field-like elements (typically
Item1,Item2, plus compiler-provided names)
11.4.5 Regular vs structural equality/ordering
Know there are different equality semantics in .NET:
- Some comparisons are “regular” and some use structural comparisons via interfaces (especially for nested tuples/collections).
11.4.7 Large tuples
Big tuples get awkward quickly. Guideline:
- If you need many elements, you probably need a named type (record/class) instead.
11.5 Alternatives to tuples
System.Tuple<...>: older, reference type, different ergonomics/perf characteristics.- Anonymous types: great for local projections (especially with LINQ).
- Named types (DTO/record): best for stable contracts and public APIs.
11.6 Uses and recommendations
11.6.1 Nonpublic APIs and easily changed code
Tuples are best when you can refactor freely (internal/private code).
11.6.2 Local variables
Great for short-lived composition (e.g., parsing + returning two values).
11.6.3 Fields
Be careful: storing tuples in fields can leak “unnamed semantics” into your design.
11.6.4 Tuples and dynamic
Tuples don’t combine nicely with dynamic (you lose compile-time shape checking and element naming clarity).