Hacking the foreach loop

David Klempfner
Level Up Coding
Published in
2 min readDec 11, 2019

--

Photo by Setyaki Irham on Unsplash

What would happen if you updated a List<T> 4294967295 times?

To follow along, you need to have read this tut first.

_version is an Int32

_version is an int, it’s also never wrapped in a checked block which means it can overflow.

Let’s look at what happens if you update a list 4294967295 times:

The loophole

When you update a list that many times, the _version ends up being one less than its initial value.

What this means is, the next time the list is updated, the _version is back to what it was at the start.

Within the list, it thinks it hasn’t been updated at all.

The list can therefore be updated, however on the next iteration when it’s updated, the _version is no longer the same as what’s in the Enumerator.

This means that on the 3rd iteration, the MoveNext() method will throw an exception.

I can’t think of how this could ever accidentally happen in a real situation, but it’s interesting none the less.

Why not stop developers from overflowing _version?

If _version was wrapped in a checked block, it would limit the number of times a List<T> could be updated.

The compiler team decided to allow any number of updates to happen, by allowing _version to cycle through all its available values.

I think the compiler team rightfully assumed no one would ever happen to try to update a List<T> right after it has been updated 4294967295 times.

A much more efficient way

The code described earlier could theoretically be written by a new developer who is not trying to break the rules.

Obviously the exact code would not be written, but there could be some complex mathematical algorithm that would result in similar code.
If you are deliberately trying to break the rules, you could use Reflection to update _version instead.

--

--

I’m a software developer who is passionate about learning how things work behind the scenes.