0

可能重复:
随机数生成器仅生成一个随机数
类 System.Random .. 为什么不是静态的?

我有一个名为的公共静态类RandomGenerator,它只有一个值 apublic static random = new Random();

这就是它的样子

    public static class RandomGenerator
    {
        public static Random random = new Random(); 
    }

我必须这样做,因为当我的代码访问随机数时,它会生成太多重复的副本(我相信它与内存中 Random 的位置有关)

上面的代码效果很好!我的代码每次调用时都会生成一个真正的随机值。我的问题是为什么随机不是 C# 语言的内置静态函数?是因为以这种方式访问​​某些东西会导致性能下降吗?我编写代码的方式是否存在明显的性能问题?

4

3 回答 3

6

MSDN 写了以下关于 Random 构造函数的内容:

默认种子值来自系统时钟并且具有有限的分辨率。因此,通过调用默认构造函数连续创建的不同 Random 对象将具有相同的默认种子值,因此将产生相同的随机数集。这个问题可以通过使用单个 Random 对象来生成所有随机数来避免。您还可以通过修改系统时钟返回的种子值,然后将这个新的种子值显式提供给 Random(Int32) 构造函数来解决此问题。

http://msdn.microsoft.com/en-us/library/h343ddh9.aspx

于 2012-12-27T08:58:19.783 回答
2

您描述的问题与随机存在或非静态无关。我想您正在创建 Random 实例,然后从该实例中获取随机值。这样,每个 Random 都是使用默认种子创建的,默认种子是当前时间,具有秒精度。由于 Random 实例是使用相同的种子创建的,因此在几秒钟内您获得了相同的值。

于 2012-12-27T08:56:15.590 回答
2

它本身不是静态的,因为 .Net 中的“随机”数字并不是真正随机的——它们是“伪随机”,这意味着它们对于统计来说足够随机,但对于密码学来说不够随机。也就是说,它们均匀分布在一个范围内,但给定种子参数,您可以预测下一个“随机”值将是什么。这就是为什么您必须实例化 Random 类(就像您在上面所做的那样)以获得随机数 - 您需要创建一个新实例,为其播种(如果您不手动播种,它会使用当前时间戳) ),然后得到“下一个”随机值。如果您使用相同的值播种 Random 类,它将产生相同系列的“随机”数字 - 使用系统时间作为种子非常有效,因为它总是在变化,

拥有像这样的静态“随机”类是获得随机值的一种方法,而无需在每次需要时都实例化一个新对象,但你在这里所做的只是实例化一个新副本。一种更有效地做到这一点的方法可能是这样的:

类 RandomNumber { 静态只读 Random r = new Random();

    public static Int32 GetNext(int maxValue)
    {
        return r.Next(maxValue);
    }

    public static Int32 GetNext()
    {
        return r.Next();
    }
}

这样,您只需实例化一次,并且您将继续重用该实例 - 每次您想要一个新的随机数时,只需调用静态类的 GetNext 方法(指定上限与否),然后您会得到一个新号码。

于 2012-12-27T08:59:05.527 回答