在静态方法中生成随机值似乎需要缓存
本文关键字:缓存 随机 静态方法 | 更新日期: 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)构造函数。