Table of Contents

Tuples

Tupler creates and inspects System.Tuple instances at runtime, without the arity being known at compile time.

Creating

using Dynamitey;

object tuple = Tupler.Create(1, "2", "3", 4);

That produces a genuine Tuple<int, string, string, int> — the same type Tuple.Create(1, "2", "3", 4) would give you, and equal to it. The element types come from the runtime types of the arguments.

Beyond seven elements

System.Tuple tops out at seven elements plus a nested TRest. Tupler.Create handles the nesting for you:

object tuple = Tupler.Create(1, "2", "3", 4, 5, 6, 7, "8", "9", 10, "11", 12);

which is exactly:

new Tuple<int, string, string, int, int, int, int, Tuple<string, string, int, string, int>>(
    1, "2", "3", 4, 5, 6, 7, Tuple.Create("8", "9", 10, "11", 12));

Writing that by hand is where the arity limit stops being a curiosity and starts being a problem. Tupler.Create is the reason you do not have to.

Inspecting

Because nesting is an implementation detail of System.Tuple rather than something callers care about, the accessors see through it:

Member Returns
Tupler.Size(tuple) The logical element count, counting through nesting
Tupler.Index(tuple, i) The element at a logical index
Tupler.First(tuple) The first element
Tupler.Second(tuple) The second element
Tupler.Last(tuple) The last element, however deeply nested
Tupler.ToList(tuple) Every element, flattened, as IList<dynamic>
Tupler.IsTuple(target) Whether the target is a tuple at all

So a twelve-element tuple reports Size of 12, not 8-with-a-nested-thing.

From a sequence

dynamic tuple = new object[] { 1, "two", 3.0 }.ToTuple();

ToTuple is an extension method on IEnumerable, so any sequence can become a tuple whose arity is decided by its length at runtime.