如何将函数扩展到Random类

时间:2012-01-27 06:26:19

标签: c# random static extension-methods random-seed

我正在尝试从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();
}

我知道这不起作用。也许我需要一个静态属性,我不确定。

2 个答案:

答案 0 :(得分:4)

您需要使用单例模式(请参阅MSDN上的Implementing Singleton in 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实例,因为您的所有代码都将使用相同的实例,因此您不会看到重复的数字。

答案 1 :(得分:4)

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可以防止多个线程使用它时无法预测;虽然在那时你无法保证可重复的订单无论如何,但至少它不会在火花中爆炸。