I have tried two different ways to get a sequence of random numbers:
// (a) works
Random random = new Random();
return Enumerable.Range(0, 20).OrderBy(n => random.Next());
// (b) does not work
return Enumerable.Range(0, 20).OrderBy(n => new Random().Next());
The first variant, where I am using random.Next()
, is working fine.
But the variant, where I have call new Random().Next()
, does NOT return random numbers; instead it returns a sequence of numbers from 0 to 20.
Now my questions are:
- What is term to denote the second type of initialization of object
new Random().Next()
in C#? - And how it is different from the first one so that I am not getting the desire output?
Random class initializes with seed on construction - this seed will be used to produce unique sequence of numbers. In case if seed is not specified -
Environment.TickCount
is used as seed. In your case, sequence is constructed so fast, that Random class gets same seed in every constructed instance. So all items return same value, and not randomly sorted.First working line, on the other hand, have single Random class instance for every enumerable item. So calling .Next() produces next random number, although seed is the same, and sequence gets randomly sorted.
Speaking of generating random sequences without duplicates - look at Fisher-Yates shuffle. Your example with Random() has side effects - executing every loop iteration changes internal state of Random() class instance, which can lead to undesired behavior - for example, if sorting algorithm relies on fact that each sequence item returns same number during sort (this is not the case with .net, but who knows - internal implementation may change in future).