Alternatives to hydrating IEnumerables

You should know that whenever you get an IEnumerable you should only enumerate it twice as some implementations don't allow you to enumerate it twice. Normally you don't get an error the second time - just no more items. But what is really the best way to handle this?

One obvious way is that when your compiler warns you that you are enumerating twice you add a nice call to a hydrate function (like this one) and that saves the day. But if you are the creator of an API is that the right thing to do in order to protect your callers? Probably not. And if the enumerable is something that takes time to enumerate like a result from a database then enumerating the whole thing just in case you need it is not necessarily a good idea.

So apart from the Hydrate function I was thinking about a few alternatives. First out is the AssertSingleEnumeration method. Why not create an extension method that throws an exception the second time it is enumerated? And what about only doing it in DEBUG-mode? This might seem temping since you get failures in your DEBUG-builds but not in release builds except that I hate different behavior for code that is supposed to be the same. In my opinion it is better to always throw an exception in this case. This gives you a clearer failure than the double enumeration warning and can be added by the provider of the enumerable rather than the consumer (as with hydrate). Still it means failing at run-time rather than compile time.

Another approach would be to create a Strict method enforces the fact that enumerables should be considered to only be enumerated once. I.e. even if the underlying implementation allows for restarting the enumeration this method would ensure single enumeration is enforced so that a second enumeration yields no elements. This will teach people a lesson at the expense of some hard to find bugs probably. But the upside is that it results in a consistent behavior of enumerables.

Yet another approach would be to create a Safe method that really is a smart version of Hydrate. I'm imaging a method that wraps the enumerable in such a way that returned entities are cached so that the enumeration can be restarted even if the underlying type does not allow it. This approach is great to keep the code working without teaching the ignorant callers anything.

So all in all I'm leaning towards the AssertSingleEnumeration that throws regardless of build type to be the best complement to the Hydrate method. What do you think?

No comments:

Post a Comment