Как расширить функции до класса Random - PullRequest
3 голосов
/ 27 января 2012

Я пытаюсь расширить функции из класса 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 ]

4 голосов
/ 27 января 2012

Параметр 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 предотвращает непредсказуемость всего этого при использовании несколькими потоками; хотя в этот момент вы не можете гарантировать повторный заказ в любом случае , но по крайней мере он не взорвется при искрах.

4 голосов
/ 27 января 2012

Вам необходимо использовать шаблон синглтона (см. Реализация синглтона в C # на MSDN)

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, потому что весь ваш код будет использовать один и тот же экземпляр, поэтому вы не увидите повторяющиеся числа.

...