How to Create Infinite Collections Using IEnumerable Properly 
Tags: csharp, dotnet, tutorial
Published: 2019-07-01 17:33:06

All C# developers faced these interfaces at some point, but how to use them? And better than that, how to use them **properly**? — Because I’ve seen a lot of mistakes with these guys.

The main point of writing this article is the fact that I lost the count about how many times I’ve seen mistakes and misunderstoods related to C# collections, so I hope to clarify some points here.

Before we start, let’s go a little back and see the cover image at the beginning of the text. It’s a visualization about how you may thinking about `IEnumerables`.

It works like a Turing Machine tape with a cursor that start pointing to `null`. This cursor move only straight forward (to right in the image), without index access and besides that, only the necessary information to iterate the collection is provided by an `IEnumerable`.

Having said that, we can start to **code**. Let’s check the `IEnumerable` implementation (with and without generics):

{% gist https://gist.github.com/gabrielschade/98d6a4983d795a2dfab6822bb9344a9f %}

And that’s all. There’s no one more line code at `IEnumerable` implementation.

What does this suggest?

`IEnumerable` actually is a `IEnumerator` factory. Now we need to check `IEnumerator` out. It’s a little bit more complex, but we can handle it.

{% gist https://gist.github.com/gabrielschade/d5e2af257f979b15de4c6132b90b52e2 %}

There’s two different interfaces, with and without using generics, just like `IEnumerable`.

The `IEnumerator` is the one who provides the information about how to iterate a collection (and `IEnumerable` that is the famous one, how unfair is that?).

In fact, when we use the `foreach` loop, C# internally calls the `GetEnumerator` of the collection we’ll iterate and at each step it calls the `MoveNext` method to move the cursor forward.

Let’s code a super simple code to iterate an IEnumerable of integers using a foreach loop:

{% gist https://gist.github.com/gabrielschade/24c8c5c2f4c7ede602203701a2916d47 %}

It’s pretty simple, isn’t?

As I said before, this code is a simple syntax sugar to another code a little bit more complex, but still a simple code snippet:

{% gist https://gist.github.com/gabrielschade/026ebe1f8f35bf20b1f76785a1861279 %}

This code is a lot more uglier but it does the exactly same thing. The first step got the enumerator using `GetEnumerator` method, after that, we can use the `MoveNext` method to iterate each of `IEnumerable` elements.

It’s interesting to notice that the `MoveNext` method is called even before we got the first element. It occurs because the enumerator cursor start pointing to one position before the first element (as shown in the tape image).

The `MoveNext` method have a design that I particularly don’t like. It does two different things.

1. One of these things is to move the cursor to the next position, which is the main purpose;
2. The secondary thing is what this method returns. It returns `true` if the cursor is pointing to a valid position after it was moved or it will return `false` if isn’t.

My problem with the design of this method is the fact that the main operation, move the cursor to the next element, is caused only by a side effect, but this is a topic for another article, let’s move on.

After call the `MoveNext` method the first time, we’ll move the cursor to the very first position of the `IEnumerable`, like the image below:

![First Position](https://thepracticaldev.s3.amazonaws.com/i/uwztccb5arhegi4lmrn6.png)

And the property `Current` just returns the value at the position that the cursor points to.

Having said that, how about to create a brand new collection containing **all integer positive numbers** that exists?

Yeah, you read it correctly, a collection with all numbers, which means, a **infinity collection**.

> Here’s a thing before we start to code, the whole point of this implementation is see how `IEnumerator` and `IEnumerable` works under the hood with a `foreach` loop, so, don’t take it as the best implementation possible for a new collection, it’s just an experiment, right?

Let’s start with an `IEnumerator`, so, just create a new class that implements `IEnumerator<int>`, It will looks like the code below:

{% gist https://gist.github.com/gabrielschade/45323f1d05830d6c875eafb63fdc87d3 %}

So, now we need to create our own stuff now. In order to create an infinite collection, we’ll use the cursor itself as a value.

Let’s create a new field called `_current` which starts at `-1` and will be incremented as the `MoveNext` method is called (usually the value is stored at the `IEnumerable`, but this isn’t a regular example, remember?)

{% gist https://gist.github.com/gabrielschade/51ac69627c32a9deaa1ec9913b900eb2 %}

Ok, but let’s understand why `_current` starts with `-1` instead of zero. The answer is pretty simple, it’s because the `MoveNext` method is called before the iteration.

Now, let’s go to `MoveNext` method, you probably already know what to do here. We need to increase the `_current` value and always return true, after all, it’s an infinite collection, so always is possible to move to the next one.

We don’t need to worry about the `Dispose` method now, so let’s implement the `Reset` method by reseting the `_current` to its initial value.

{% gist https://gist.github.com/gabrielschade/10828d6cde6cc55b9995d8641fea73af %}

Now, let’s implement our collection itself. It’ll be easy, trust me. All we need is implement the `IEnumerable<int>` interface and return an instance of our `IEnumerator`.

{% gist https://gist.github.com/gabrielschade/76c3379ff390b34c15b7c086b3fd4aa1 %}

Maybe for some reason, you may need return new instances any time you call `GetEnumerator`, but for our example, only one instance is enough.

Now we can use our own class inside of a `foreach` loop:

{% gist https://gist.github.com/gabrielschade/f3b422fa46491705d72e4a5d44b3be26 %}

And we can get the next, the next, and the next and keep doing that **forever**.

![Infinite Collection](https://thepracticaldev.s3.amazonaws.com/i/doxnaq49xlje20y9l7fr.png)

How cool is that?

So, everything was implemented correctly, right? — Not exactly.

Let’s force an interruption by using `break`:

{% gist https://gist.github.com/gabrielschade/2a36759f3b7c5b14c5872431c4a0eed3 %}

**_BANG!_** — An exception was thrown.

Why this exception was thrown? — Simple, the `Dispose` method wasn’t implemented yet.

Right, but when it’s called?

Just after the loop! In order to remember, let’s reimplement it without `foreach` sugar syntax, in other words, by using `while` loop:

{% gist https://gist.github.com/gabrielschade/11ac3c69e403662eab4eca6fc7fa8819 %}

Now the things are more clear, aren’t they?

When we iterate across an `IEnumerable` we use the `using` keyword, and as you probably already know, the `Dispose` method is called at the end of the using scope.

The reason why the `Dispose` method is called is a lot more clear with this syntax, even though it looks worse. We can fix it just by calling `Reset` method at `Dispose`.

>**Warning**
>
>This **isn’t** the best way to implement the `Dispose` method whatsoever, this is just an experiment, ok?

Now, you have your own infinite collection, it’s time to snapping your fingers (Like Thanos did)!

See you in the next post!