我尝试了两种不同的方法来获得一系列随机数:
// (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());
Run Code Online (Sandbox Code Playgroud)
我正在使用的第一个变体random.Next()工作正常.
但是我调用的变体new Random().Next()并不返回随机数; 相反,它返回一个从0到20的数字序列.
现在我的问题是:
new Random().Next()C#中对象的第二种初始化?随机类在构造时用种子初始化 - 该种子将用于产生唯一的数字序列.如果未指定种子 - Environment.TickCount用作种子.在您的情况下,序列构造得如此之快,以至于Random类在每个构造的实例中都获得相同的种子.所以所有项都返回相同的值,而不是随机排序.
另一方面,第一个工作行为每个可枚举项都有单个Random类实例.因此,调用.Next()会产生下一个随机数,尽管种子是相同的,并且序列会随机排序.
说到生成无重复的随机序列 - 请看Fisher-Yates shuffle.使用Random()的示例有副作用 - 执行每个循环迭代会更改Random()类实例的内部状态,这会导致不期望的行为 - 例如,如果排序算法依赖于每个序列项在排序期间返回相同的数字的事实(这不是.net的情况,但谁知道 - 未来内部实施可能会发生变化).