我在其中一个班级中发现了一个奇怪的行为。如果我调试程序它按预期工作 - 它返回随机长度的数组,填充了来自“string [] basicJobs”的随机字符串元素,它们作为类构造函数内的参数传递。 如果我只是按F5启动程序,就会出现奇怪的行为。在这种情况下,CreateWork()返回一个随机长度但填充了IDENTICAL字符串的数组。
class WorkCreator
{
private string[] basicJobs;
private string[] createdJobs;
private Random randWorkCount = new Random();
public WorkCreator(string[] basicJobs)
{
this.basicJobs = basicJobs;
}
public string[] CreateWork()
{
Random randomBasicJob = new Random();
this.createdJobs = new string[randWorkCount.Next(3, 20)];
for (int i = 0; i < this.createdJobs.Length; i++)
{
// createdJobs[i] = this.basicJobs[randomBasicJob.Next(basicJobs.Length)];
createdJobs[i] = this.basicJobs[Convert.ToInt16(new Random().Next(this.basicJobs.Length))];
}
return createdJobs;
}
}
我找到了一个解决方法(CreateWork()
内部代码的注释行),但我仍然想知道这些行为的原因是什么...... :(。我正在使用Visual Studio Community 2013
和.Net 4.5
。
感谢您的帮助。
答案 0 :(得分:2)
在documentation for System.Random(第一段)中,它的内容为:
默认种子值源自系统时钟并具有有限的分辨率。因此,通过调用默认构造函数紧密连续创建的不同Random对象将具有相同的默认种子值,因此将生成相同的随机数集。使用单个Random对象生成所有随机数可以避免此问题。您还可以通过修改系统时钟返回的种子值,然后将此新种子值显式提供给Random(Int32)构造函数来解决此问题。有关更多信息,请参阅Random(Int32)构造函数。
这可能是您代码中发生的事情的最佳解释。
如果您单步执行程序,则会有更多时间过去,种子会有所不同,从而获得所需的字符串。如果你只是运行程序,种子是相同的,因为行执行没有太多延迟。