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 の 2 番目の関数です。多くのクラスが Random クラスとやり取りできるものが必要ですが、それらのクラスはすべて同じインスタンスを持つ必要があります。

ReseedRandom を呼び出したとします...他のクラスが新しいシードを更新または更新する必要がある可能性はありますか?

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

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

私はこれがうまくいかないことを知っています。静的プロパティが必要かもしれませんが、よくわかりません。

4

2 に答える 2

5

パラメータはby-valです。つまり、呼び出し元thisは値への再割り当てに気付かないため、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); }
    } 
    ...
}

hereを使用すると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 に答える