I randomly sorted an IEnumerable
. I keep printing out the same element, and getting a different result.
string[] collection = {"Zero", "One", "Two", "Three", "Four"};
var random = new Random();
var enumerableCollection = collection.OrderBy(e => random.NextDouble());
Console.WriteLine(enumerableCollection.ElementAt(0));
Console.WriteLine(enumerableCollection.ElementAt(0));
Console.WriteLine(enumerableCollection.ElementAt(0));
Console.WriteLine(enumerableCollection.ElementAt(0));
Console.WriteLine(enumerableCollection.ElementAt(0));
Every write gives a different random element. Why is the order not preserved?
Many of the previous responses are technically correct, but I think it is useful to look directly at the implementation for Enumerable.
We can see that the the ElementAt calls GetEnumerator, which in turn yields on an iteration of the the current grouping.
If you aren't familiar with yeild see yield.
For the given example, the current grouping is
Which means that we are endlessly iteratorating over collection (look at the inifinite loop of the yield) and returning the resolution of the grouping for each element which executes against random.NextDouble().
Therefore, the non-deterministic nature here is due to the non-deterministic nature of the random grouping. This is expected behavior for the LINQ terminal statements (.List(), toArray() ect.) but can be confusing if you attempt to utilize them beforehand.