6

By default, when using C# 7 tuples, the items will named like Item1, Item2, and so on.

I know you can name tuple items being returned by a method. But can you do the same inline code, such as in the following example?

foreach (var item in list1.Zip(list2, (a, b) => (a, b)))
{
    // ...
}

In the body of the foreach, I would like to be able to access the tuple at the end (containing a and b) using something better than Item1 and Item2.

Community
  • 1
  • 1
Gigi
  • 28,163
  • 29
  • 106
  • 188

2 Answers2

17

Yes, you can, by deconstructing the tuple:

foreach (var (boo,foo) in list1.Zip(list2, (a, b) => (a, b)))
{
    //...
    Console.WriteLine($"{boo} {foo}");
}

or

foreach (var item in list1.Zip(list2, (a, b) => (a, b)))
{
    //...
    var (boo,foo)=item;
    Console.WriteLine($"{boo} {foo}");
}

Even if you named the fields when declaring the tuple, you'd need the deconstruction syntax to access them as variables:

foreach (var (boo,foo) in list1.Zip(list2, (a, b) => (boo:a, foo:b)))
{
    Console.WriteLine($"{boo} {foo}");
}

If you want to access the fields by name without deconstructing the tuple, you'll have to name them when the tuple is created:

foreach (var item in list1.Zip(list2, (a, b) => (boo:a, foo:b)))
{
    Console.WriteLine($"{item.boo} {item.foo}");
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • 1
    This is excellent, I have read various articles on C# 7 tuples and haven't seen the colon syntax documented anywhere. – Gigi Apr 27 '17 at 09:31
  • @Gigi you probably did, in the "deconstruction" sections of these articles. *Any* type can be deconstructed this way, as long as it has a `Deconstruct` member or *extension* method. Tuples are a natural fit for this. You could create extension deconstruction methods for types that don't have them now, eg KeyValuePair just begs for `void Deconstruct(this KeyValuePair,out TK key, out TV value) ...` method – Panagiotis Kanavos Apr 27 '17 at 09:33
  • Example usage of the new tuple syntax with `ref`, `out`, and `ref local` can be found [here](https://stackoverflow.com/a/46019408/147511) – Glenn Slayden Sep 03 '17 at 20:11
3

Note that C# 7.1 will add a refinement on tuple names. Not only can tuple elements be named explicitly (using the name-colon syntax), but their names can be inferred. This is similar to the inference of member names in anonymous types.

For instance, var t = (a, this.b, y.c, d: 4); // t.a, t.b, t.c and t.d exist

See https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/infer-tuple-names.md for more details.

Julien Couvreur
  • 4,473
  • 1
  • 30
  • 40