Runtime: ValueTuple AsEnumerable extension method

Created on 27 Feb 2017  路  12Comments  路  Source: dotnet/runtime

For ValueTuple which have the same object it would be similar to collection so I think we should have some way to iterate its values. And so it could work with linq

```C#
public static class TupleExt
{
// sample for Tuple 3
public static IEnumerable AsEnumerable(this ValueTuple tuple)
{
yield return tuple.t0;
yield return tuple.t1;
yield return tuple.t2;
}
}

ValueTuple vector;

var countPositive = vector.AsEnumerable().Count((p) => p > 0);
```

api-needs-work area-System.Runtime up-for-grabs

All 12 comments

What are the real-world use cases? How common are they?

@karelz first thing come in my mind is iterate some constant with new tuple syntax

```C#
var items = (0,1,2).AsEnumerable().Select((i) => array[i]);

foreach(var name in ("John","Adam","Mike").AsEnumerable())
Console.WriteLine(name);
```

With Linq we would be able to do many things for constant collection

OK, it seems somewhat useful. I'd be curious how many people will find it useful - i.e. if it belongs into CoreFX, or if we should leave it up to developers to create their own extension methods (in case it is rare-ish use case).

cc @jcouv

@Thaina There's already a syntax for that:

```c#
var items = new[] {0,1,2}.Select((i) => array[i]);

foreach(var name in new[] {"John","Adam","Mike"})
Console.WriteLine(name);
```

I think in these cases, directly creating the array is more readable, so those cases are not very convincing reasons to add the method for me.

@svick I am not sure what would be better between creating new array and make memory footprint vs push/pop yield stack if it all constant values

@Thaina the question is - is the syntax needed in perf-sensitive context in real-world situations?

Note: We hold higher bar for new APIs in CoreFX - we need clear consensus it is useful and will be used reasonably by many developers, otherwise we would just add marginal APIs that are rarely used and we would drown in them (from cost perspective, incl. docs, and also from cluttered API surface perspective).

@karelz In my opinion anywhere we have constant iterator we should promote this syntax instead of create inline array like new[]{}. It might not seem affect performance much but on server a function might end up being called by million

We might create array outside function to avoid array creation but then that array would be exposed to other function, it not encapsulated in local where it only needed

To create constant iterable tuple fit all these. We could also made it readonly if there are readonly local present

But will it really worth is what I don't know, it up to many people to decide

@karelz Actually, might not possible, but I wish we could directly iterate on ValueTuple

```C#
var odds = (1,3,5,7).Select((i) => arr[i]);

foreach(var i in (0,1,2,3,4))
{
}
```

If I wanted to enumerate a value tuple I'd perhaps consider using a struct the same way List<T> does for performance and allocation reasons, while still allowing it to be boxed for linq operations. I'm not sure it would come up that often though.

Note that the ITuple interface (which will be used for some future pattern language feature) can be used for this, although it requires casting from object.

C# public interface ITuple { int Length { get; } object this[int index] { get; } }

Related to this proposal https://github.com/dotnet/csharplang/issues/600

If that proposal pass this issue would not needed

I've seen few-to-no real-world cases where this would be valuable, and for those where it's needed, as @jcouv points out a for loop can be used with ITuple, or anyone can write the simple extension methods to do this themselves and even publish it to NuGet for others to consume. Given this has been open for several years with very little interest, I'm closing it. Thanks for the suggestion.

Was this page helpful?
0 / 5 - 0 ratings