在静态方法中生成随机值似乎需要缓存

本文关键字:缓存 随机 静态方法 | 更新日期: 2023-09-27 18:12:53

我在静态类中有一个静态方法,可以生成随机字符串,像这样:

public static class DataGenerator
    {
        public static string GenerateRandomString(int length)
        {
            const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var random = new Random();
            return new string(
                Enumerable.Repeat(Chars, length)
                    .Select(s => s[random.Next(s.Length)])
                    .ToArray());
        }
}

当我从同一个调用函数多次调用这个方法时,它似乎缓存了生成的字符串。

下面是一个用法的例子:

var item = new CodeDescActivePo()
                {
                    Active = true, 
                    Code = DataGenerator.GenerateRandomString(10), 
                    Description = DataGenerator.GenerateRandomString(10)
                };

请注意,有2个调用GenerateRandomString,我希望有2个唯一的随机数,在这种情况下代码和描述总是相同的。

为什么GenerateRandomString每次不生成一个新的随机数?

在静态方法中生成随机值似乎需要缓存

您一起呼叫var random = new Random();太快了。由于默认的种子是基于时间的,所以种子是相同的。最好只创建一次这个变量,每次需要时创建Random.Next()

public static class DataGenerator
{
    private readonly static Random random = new Random();
    public static string GenerateRandomString(int length)
    {
       //etc etc using random.Next()
    }
}

因为每次调用都使用new Random()实例。默认情况下,它使用当前系统时间作为种子,这意味着同时创建的多个Random实例将给出相同的值。

Random实例改为static字段,以使其在调用之间保持活动

问题:

从MSDN

默认种子值来自系统时钟,具有有限的分辨率。因此,通过调用默认构造函数连续创建的不同Random对象将具有相同的默认种子值,因此将产生相同的随机数集。

解决方案:再次来自MSDN

这个问题可以通过使用一个随机对象来生成所有的随机数来避免。您还可以通过修改系统时钟返回的种子值,然后显式地将这个新的种子值提供给Random(Int32)构造函数来解决这个问题。有关更多信息,请参阅Random(Int32)构造函数。