Convert ValueTuple to IEnumerable

Is there an easier way to do the following:

public static class ValueTupleAdditions { public static IEnumerable<object> ToEnumerable<A, B>(this ValueTuple<A, B> tuple) { yield return tuple.Item1; yield return tuple.Item2; } public static IEnumerable<object> ToEnumerable<A, B, C>(this ValueTuple<A, B, C> tuple) { yield return tuple.Item1; yield return tuple.Item2; yield return tuple.Item3; } [etc] } 

EDITOR: Since people are asking for a use case, you are here.

 using Xunit; namespace Whatever { public class SomeTestClass { public static IEnumerable<(string, Expression<Func<string, string>>, string)> RawTestData() { yield return ("Hello", str => str.Substring(3), "lo"); yield return ("World", str => str.Substring(0, 4), "worl"); } public static IEnumerable<object[]> StringTestData() { return RawTestData().Select(vt => new object[] { vt.Item1, vt.Item2, vt.Item3 }); // would prefer to call RawTestData().Select(vt => vt.ToArray()) here, but it doesn't exist. } [Theory, MemberData(nameof(StringTestData))] public void RunStringTest(string input, Expression<Func<string, string>> func, string expectedOutput) { var output = func.Compile()(input); Assert.Equal(expectedOutput, output); } } } 
+7
c # ienumerable valuetuple
source share
2 answers

A little reflection:

 namespace ConsoleApp1 { using System; using System.Collections.Generic; using System.Linq; public class Program { public static void Main() { var tuple = (1, 2, 3, 4, 5, 6, 7); var items = ToEnumerable(tuple); foreach (var item in items) { Console.WriteLine(item); } } private static IEnumerable<object> ToEnumerable(object tuple) { if (tuple.GetType().GetInterface("ITupleInternal") != null) { foreach (var prop in tuple.GetType() .GetFields() .Where(x => x.Name.StartsWith("Item"))) { yield return prop.GetValue(tuple); } } else { throw new ArgumentException("Not a tuple!"); } } } } 
+2
source share

One way to do this is through the ITuple interface .

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

It is available only in .NET Core 2.0, Mono 5.0 and the next version of the .NET Framework (unreleased, follow 4.7). It is not (and never will be) available as an addition to the old frameworks through the ValueTuple package.

This API is intended for use by the C # compiler for further work with templates.

+2
source share

All Articles