Elvis and King Concat
I hate LINQ's <a href="https://msdn.microsoft.com/en-us/library/bb302894%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396">Enumerable.Concat</a>
when bringing together IEnumerable
s. Not the behaviour (I love that!) but rather how code ends up looking when you use it. Consider this:
In this example I'm bringing together 2 collections, either of which may be null (more on that later). I think we can all agree this doesn't represent a world of readability. I've also had to create a custom class ConcatObj
because you can't create an empty array for an anonymous type in C#.
ConcatMany
#
Attempt #1: After toying around with a bunch of different ideas I created this extension method:
Thanks to the joy of params
this extension allows me to bring together multiple IEnumerables into a single one but has the advantage of considerably cleaner calling code:
For my money this is more readable and intent is clearer. Particularly as the number of contributing IEnumerables goes up. The downside is that I can’t use anonymous objects because you need to tell the compiler what the type is when using <a href="https://msdn.microsoft.com/en-us/library/bb341042%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396">Enumerable.Empty</a>
.
Wouldn't it be nice to have both:
- Readable code and
- Anonymous objects?
EnumerableExtensions.Create
#
Attempt #2: After batting round a few ideas (thanks Matt) I settled on this implementation:
Which allows for calling code like this:
That's right; anonymous types are back! Strictly speaking the Concat
method above could be converted into a single SelectMany
(and boy does ReSharper like telling me) but I'm quite happy with it as is. And to be honest, I so rarely get to use yield
in my own code; I thought it might be nice to give it a whirl 😊
#
What Gives Elvis?If you look closely at the implementation you'll notice that I purge all null
s when I'm bringing together the Enumerable
s. For why? Some may legitimately argue this is a bad idea. However, there is method in my "bad practice".
I've chosen to treat null
as "not important" for this use case. I'm doing this because it emerges that ASP.NET MVC deserialises empty collections as nulls. (See here and play spot the return null;
) Which is a pain. But thanks to the null purging behaviour of EnumerableExtensions.Create
I can trust in the null-conditional (Elvis) operator to not do me wrong.