Reputation: 193352
All I want is a pragmatic random number generator in C# so I can say e.g.
int dummyAge = MathHelpers.GetRandomNumber(20,70);
and have it seem quasi random, e.g. to generate dummy data.
Most stack overflow questions on this topic and on the web get into a philosophical discussions on true randomness which is not what I'm interested at the moment, e.g. I did one in PHP a long time ago which uses milliseconds/sleep which is fine for dummy data, I'm just trying to do this in C# quick.
Does anyone have a quick half-decent C# random number generator based on some time seed, etc. or, how could I change the following code so that it always doesn't generate the same 5 number in a row?
using System;
namespace TestRandom23874
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10));
Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10));
Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10));
Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10));
Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10));
Console.ReadLine();
}
}
public class MathHelpers
{
public static int GetRandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
}
}
Upvotes: 8
Views: 2206
Reputation: 1502016
BFree's answer is fine, but I think it's also worth mentioning a slightly different pattern - passing the Random
instance into anything that needs it, rather than always using a single instance via a static variable. The downside of the latter approach is that Random
isn't thread-safe. You either need some locking, or thread-local variables, or avoiding using multiple threads to start with. So I would adjust the original code in the question to:
using System;
namespace TestRandom23874
{
class Program
{
static void Main(string[] args)
{
Random rng = new Random();
Console.WriteLine("the random number is: {0}",
MathHelpers.GetRandomNumber(rng, 1, 10));
Console.WriteLine("the random number is: {0}",
MathHelpers.GetRandomNumber(rng, 1, 10));
Console.WriteLine("the random number is: {0}",
MathHelpers.GetRandomNumber(rng, 1, 10));
Console.WriteLine("the random number is: {0}",
MathHelpers.GetRandomNumber(rng, 1, 10));
Console.WriteLine("the random number is: {0}",
MathHelpers.GetRandomNumber(rng, 1, 10));
}
}
public class MathHelpers
{
public static int GetRandomNumber(Random random, int min, int max)
{
return random.Next(min, max);
}
}
}
It's just basic inversion of control, really. You might have one static RNG with locking round it, used to generate a new instance of Random
in a thread-safe way when you need it (by randomly generating a seed and then using that to create the instance) then reusing the Random
throughout a particular single-threaded set of operations.
Upvotes: 2
Reputation: 103750
public class MathHelpers
{
private static Random random = new Random();
public static int GetRandomNumber(int min, int max)
{
return random.Next(min, max);
}
}
This way, you're not creating a new Random object every time, rather you're reusing the same one. When you recreate a new one quickly enough, they will yield the same results. If however, you reuse an existing one, you'll get randomness.
Upvotes: 13