3

我正在尝试从 Random 类扩展功能。

public static class RandomExtensions
{
    public static void NextEven(this Random rnd, int min, int max)
    {
        // ...
    }

    public static void ReseedRandomNumberGenerator(this Random rnd, int? seed = null)
    {
        rnd = seed.HasValue ? new Random(seed.Value) : new Random(); 
    }
}

但我怀疑的是第二个函数ReseedRandomNumberGenerator。我需要许多类可以与 Random 类交互的东西,但所有这些类都应该具有相同的实例。

假设我调用 ReseedRandom ... 可能比其他类应该刷新或更新新种子?

public class A()
{
        protected Random Random = new Random();
}

public class B()
{
        protected Random Random = new Random();
}

我知道这行不通。也许我需要一个静态属性,我不确定。

4

2 回答 2

5

this参数是 by-val,意思是:调用者不会注意到你对值所做的任何重新分配,因此你的方法Reseed...不会做任何调用者会注意到的事情。要做到这一点,听起来你想要一个静态实例,但是你也需要注意线程安全之类的事情。

就个人而言,我会创建一个单独的 API,例如:

public static class MyRandom {
    static Random random = new Random();
    static readonly object sync = new object();
    public static void Seed(int seed) {
        lock(sync) { random = new Random(seed); }
    }
    public static int Next() {
        lock(sync) { return random.Next(); }
    }
    public static int Next(int max) {
        lock(sync) { return random.Next(max); }
    } 
    ...
}

lock当被多个线程使用时,这里的使用可以防止这一切变得不可预测;虽然在那个时候你不能保证一个可重复的订单但至少它不会在火花中爆炸。

于 2012-01-27T06:40:25.570 回答
4

您需要使用单例模式(请参阅MSDN 上的在 C# 中实现单例)

public class RandomSingleton
{
   private static Random instance;

   private RandomSingleton() {}

   public static Random Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Randon();
         }
         return instance;
      }
   }
}

然后,您可以在代码中的任何位置访问相同的 Random 实例,如下所示:

RandomSingleton.Instance.NextInt(24);

请注意,无需重新播种此Random实例,因为您的所有代码都将使用相同的实例,因此您不会看到重复的数字。

于 2012-01-27T06:37:54.940 回答