我需要创建一个独特行块来测试我正在处理的不同项目。
所以我创建了一个简单的程序来生成一个X长度的随机字符串。
问题在于,如果我调用它一次,我会得到一个随机字符串,如果我再次调用它(例如在for循环中),我会得到完整循环执行的相同字符串。
我有一种感觉,它被缓存或其他东西,但我不知道.net这样做,我只是在这一点上感到困惑。
致电代码:
StreamWriter SW = new StreamWriter("c:\\test.txt");
int x = 100;
while (x >0)
{
SW.WriteLine(RandomString(20));
x--;
}
以下是方法:
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
Random randomNumber = new Random();
for (int i = 0; i <= Length; ++i)
{
int x = randomNumber.Next(65, 122);
sb.Append(Convert.ToChar(x));
}
return sb.ToString();
}
,这是输出:
"VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
..................
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB"
那么是什么让我认为Random.next()总会返回一个新的随机数?
答案 0 :(得分:25)
您正在及时创建Random
个实例。每个实例都使用系统时钟进行初始化,并且由于时钟没有改变,您可以一遍又一遍地获得相同的随机数序列。
创建Random
类的单个实例并反复使用它。
使用using
关键字,以便在完成后StreamWriter
关闭并处理。如果您使用for
关键字,则更容易识别循环代码。
using (StreamWriter SW = new StreamWriter("c:\\test.txt")) {
Random rnd = new Random();
for (int x = 100; x > 0; x--) {
SW.WriteLine(RandomString(rnd, 20));
}
}
该方法将Random
对象作为参数。
另外,使用length来初始化StringBuilder并使用正确的容量,这样它就不必在循环期间重新分配。使用&lt;运算符而不是循环中的&lt; =否则您将创建一个比length
参数指定的字符长一个字符的字符串。
private static string RandomString(Random rnd, int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int x = rnd.Next(65, 122);
sb.Append((char)x);
}
return sb.ToString();
}
答案 1 :(得分:12)
请参阅MSN的Random constructor description,此部分:
默认种子值派生自 系统时钟并且有限 解析度。结果,不同 在中创建的随机对象 通过致电来接近接班人 默认构造函数将具有 相同的默认种子值, 因此,将产生相同的集合 随机数。
所以要么在程序开头只调用一次Random()构造函数,要么使用Random(int32)构造函数并自己定义一个变化的种子。
答案 2 :(得分:4)
因为您在每次调用中都创建了一个新的Random对象。
只需将randomNumber移出方法并使其成为类成员。
private Random randomNumber = new Random();
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
//...
}
所有软件随机生成器都是'伪随机',它们根据(起始)种子生成一系列数字。使用相同的种子,它们产生相同的序列。有时这很有用。如果要生成程序以在每次运行时生成相同的序列,可以使用new Random(0)
。
编辑:显然.Net Random类是自动播种,我不知道。所以这是一个时间问题,正如其他人所指出的那样。
答案 3 :(得分:3)
答案 4 :(得分:3)
只声明randomNumber一次
public class MyClass
{
private static Random randomNumber = new Random();
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i ... Length; ++i)
{
int x = MyClass.randomNumber.Next(65, 122);
sb.Append(Convert.ToChar(x));
}
return sb.ToString();
}
}
答案 5 :(得分:1)
随机数的种子都是相同的,因为它花费的时间很短,实际上每次都使用相同的种子重新创建随机生成器,因此Next()调用返回相同的随机值。 / p>