Tuple deconstruction for an infinite stream
Sometimes we want to generate a flexible, or even infinite, stream of things; C# allows us to create a source (a “generator”) of things with a yield return
block. I wanted to play with doing that in C# and couple it to tuple deconstruction.
We can support tuple deconstruction in C# by implementing an overload of the Deconstruct<T>
method. Here’s a simple example:
This won’t work for infinite streams, however, as Count
won’t return. You can try it with a simple generator of random numbers:
You can avoid that by using Any
instead of Count
.. and better the opening ternary can be collapsed to list.First()
if you’re happy with the default InvalidOperationException
thrown by First
for an empty list.
In theory we’re left with a similar problem for the two-parameter Deconstruct<T>
overload. The solution is to implement it in term of the single-parameter version:
This isn’t a generic answer however, as it’ll break for finite streams of shorter length than your most-overloaded Deconstruct<T>
. You could pad with FirstOrDefault
but you’d want to very clearly document that behaviour, as it might not be what the client expects.
Devs with a functional background will recognise the first as something like a cons
operation. Typically cons
would be used with a pattern matching-style operation that explicitly handles the empty-stream case outside of the cons
implementation - something like:
So if you find yourself worrying about what to do about empty streams in your Deconstruct<T>
overload, perhaps consider making that the responsibility of your calling method instead.