IEnumerable
ランダムな値を取得するにはどうすればよいですか? クラスRandomが実装されていないことに失望していますIEnumerable<int>
。
質問する
519 次
3 に答える
8
新しい値を取得する拡張メソッドを記述します。yield return
public static IEnumerable<int> GetRandomValues(this Random instance)
{
while(true)
{
yield return instance.Next();
}
}
于 2012-07-11T14:49:34.980 に答える
3
たとえば、これはかなり簡単に自分で実装できます。
public IEnumerable<int> RandomInts(int below)
{
Random r = new Random();
while (true) yield return r.Next(below);
}
于 2012-07-11T14:50:43.593 に答える
1
IEnumerable<int>
Random クラスのインスタンスを持つことのいくつかの問題点は次のとおりです。
- 乱数発生器には無限に多くの要素があるため、要素に対して
foreach
構成またはループを使用しても決して終了しません。 - fromが返す
IEnumerator<int>
インスタンスには、列挙子をコレクションの先頭にリセットする関数があります。過去に生成されたように、正しい動作を仮定すると、これは最初に生成された乱数を返すはずです。getEnumerator
IEnumerable<int>
Reset
最後の問題は、少なくとも 2 つの方法で解決できます。
- 既に生成された値のリストを保持すると、メモリ効率があまり良くない可能性がありますが、少なくともリセット後に常に同じ値を返すことが保証されます。
- 開始シードを維持し
Reset
、新しいジェネレーターが呼び出されると、以前のシードでインスタンス化できます。Random の他のすべてのランダム生成メソッドは、アクセスされないように非表示にする必要があります。
簿記の方法があまり良くないので、私は2番目のバージョンに行きます. 以下に示すように、これは非常に大きなクラスです。
public class RandomInt : IEnumerable<int>
{
int seed;
public RandomInt ()
{
seed = new Random ().Next();
}
public IEnumerator<int> GetEnumerator ()
{
return new InternalEnumerator (seed);
}
protected class InternalEnumerator : IEnumerator<int>
{
Random randomGen;
int current;
int seed;
protected InternalEnumerator (int seed)
{
this.seed = seed;
}
#region IEnumerator implementation
public bool MoveNext ()
{
if (randomGen == null)
randomGen = new Random (seed);
current = randomGen.Next();
return true;
}
public void Reset ()
{
randomGen = null;
}
public int Current {
get {
if (randomGen == null)
throw new InvalidOperationException ("Enumerator in reset state");
return current;
}
}
#endregion
}
}
于 2012-07-11T15:26:39.157 に答える