Looking through the source code (decompiled using JetBrains Rider 2019.1.2) of System.ValueTuple
I noticed that the method that creates an 8-tuple wraps the last parameter in a tuple of its own. What is the point of wrapping an element in a 1-tuple?
public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(
T1 item1,
T2 item2,
T3 item3,
T4 item4,
T5 item5,
T6 item6,
T7 item7,
T8 item8)
{
return new ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create<T8>(item8));
}
Decompilation header:
// Decompiled with JetBrains decompiler
// Type: System.ValueTuple
// Assembly: System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
// MVID: CE11CF72-ED8D-4122-8743-9D6985631221
// Assembly location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.0.0-preview3-27503-5\System.Private.CoreLib.dll
A ValueTuple
is a type with the ability to store 7 values and say 'and I will put the leftovers in another ValueType here' (i.e. the Rest
property).
I still don't understand what is the advantage of wrapping the last parameter in another ValueTuple. For example, why not force the programmer declare a custom type and use it instead?
For two reasons:
a) If you do that, you effectively went from 7 to 8 types / values. But that doesn't solve the problem. What about 9? 10?
b) Having Rest
be ValueType
means you can support as many types as you want. And the code that deals with the first 7 can be the same as the code that deals with the next 7 etc etc. Since it is ValueType
all the way down.
Also, note that if you already have a ValueType
as the eight parameter, call the constructor rather than Tuple.Create
(to avoid wrapping the ValueTuple
in another ValueTuple
).