Deconstructing arrays in C#7
C#7 introduces new feature - object deconstruction. Tuples have built-in support for deconstruction, but for user defined types a deconstructor must be defined.
Which means that out of the box array deconstruction is not possible. Luckily for us, it is quite easy to add using extension methods. A user named ufcpp
suggested the following code:
public static class Extensions
{
public static void Deconstruct<T>(this T[] arr, out T first, out Span<T> rest)
{
first = arr.Length > 0 ? arr[0] : default(T);
rest = new Span<T>(arr).Slice(1);
}
}
Note: to use
Span<T>
add a prerelease packageSystem.Memory
.
This allows us to write the following code:
var (first, _) = new[] { 0, 1, 2, 3, 4 };
// first is now 0
To extract more than one element a new extension method can be added that has the signature public static void Deconstruct<T>(this T[] arr, out T first, out T second, out Span<T> rest)
. It is obvious that to extract first N parameters we need a method that handles N parameters.
But, if we enable deconstruction of Span<T>
with the following code:
public static void Deconstruct<T>(this Span<T> span, out T first, out Span<T> rest)
{
first = span.Length > 0 ? span[0] : default(T);
rest = span.Slice(1);
}
It is now possible to write LISPy code:
var (first, (second, _)) = new[] { 0, 1, 2, 3, 4 };
var (x, (y, (z, _))) = new[] { 0, 1, 2, 3, 4 };
But if too many parenthesis give you headache, consider writing overloads for desired number of parameters to extract.