Is there a saner 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]
}
EDIT: Since people are asking for a use case, here you go.
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);
}
}
}
One way to do this is via the
ITuple
interface.It is only available in .NET Core 2.0, Mono 5.0 and the next version of .NET Framework (unreleased, following 4.7). It is not (and will never be) available as an add-on to older frameworks via the ValueTuple package.
This API is designed for usage by the C# compiler for future work on patterns.
A bit of reflection: