为什么这个方法每次都返回相同的随机字符串?

时间:2009-04-30 16:40:29

标签: c# .net text random char

我需要创建一个独特行块来测试我正在处理的不同项目。

所以我创建了一个简单的程序来生成一个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()总会返回一个新的随机数?

6 个答案:

答案 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>