Why is LINQ non-deterministic?

  • A+
Category:Languages

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?

See it on .NET Fiddle

 


Linq defers execution until it is absolutely necessary. You can think of enumerableCollection as the definition of how you want the enumeration to work, rather than the result of a single enumeration.

So each time you enumerate it (which you're doing when you call ElementAt) it will re-enumerate your original collection, and since you've chosen to order randomly, the answer is different each time.

You can make it do what you were expecting by adding .ToList() on the end:

var enumerableCollection = collection.OrderBy(e => random.NextDouble()).ToList(); 

This performs an enumeration, and stores the result in a List. By using this, the original list won't be re-enumerated each time you enumerate the enumerableCollection.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: