Why does this method result in an infinite loop?

The key to answering this is deferred execution. When you do this

items = items.Select(item => items.First(i => i == item));

you do not iterate the items array passed into the method. Instead, you assign it a new IEnumerable<int>, which references itself back, and starts iterating only when the caller starts enumerating the results.

That is why all your other fixes have dealt with the problem: all you needed to do is to stop feeding IEnumerable<int> back to itself:

  • Using var foo breaks self-reference by using a different variable,
  • Using return items.Select... breaks self-reference by not using intermediate variables at all,
  • Using ToList() breaks self-reference by avoiding deferred execution: by the time items is re-assigned, old items has been iterated over, so you end up with a plain in-memory List<int>.

But if it’s feeding on itself, how does it get anything at all?

That’s right, it does not get anything! The moment you try iterating items and ask it for the first item, the deferred sequence asks the sequence fed to it for the first item to process, which means that the sequence is asking itself for the first item to process. At this point, it’s turtles all the way down, because in order to return the first item to process the sequence must first get the first item to process from itself.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)