Using random numbers in C#/.NET 🎲
Tags: csharp, dotnet
Published: 2020-10-12 16:07:49

There will be times while coding, when you might need to simulate some sort of probability or non-deterministic behavior. Usually the simplest way of doing that is using random numbers.

Luckily for us mortals, C# has a very easy way of approximating random numbers. All you have to do is use the `Random` class from the .NET framework to generate a pseudo-random number:

```C#
using System;

namespace GeneratingRandomNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();

            Console.WriteLine(random.Next(1, 10));
            Console.ReadKey(true);
        }
    }
}
```

The above code will initiate a new `Random` number generator for you, and calling the `Next` function will then return a pseudo-random number between the min and max values you provide as parameters.

However, the above code actually has a couple of problems. Let's talk about those.

First of all, you might have noticed that I keep referring to these "random" numbers as _pseudo-random_. This is because a number returned by the `random.Next` method is not really completely random. Simply put, the `Random` class uses a complex algorithm that makes it _seem_ like the numbers are random.

According to the [.NET documentation](https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netcore-3.1), the algorithm takes a seed that is time-based. This means that if we create multiple `Random` objects at the same time, they will all produce the same sequence of numbers. You can actually test this by doing something like this:

```C#
Random random = new Random();
Random anotherRandom = new Random();

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(random.Next(1, 10) + ", " + anotherRandom.Next(1, 10));
}

Console.ReadKey(true);
```

There are some instances where we might want to reproduce the same sequence of seemingly random numbers. However, in most cases we would like to always produce a different sequence. A good way to ensure that this is the case, is to make our `Random` object static, and always derive all random numbers from the same object.

We might thus want to do this:

```C#
using System;

namespace GeneratingRandomNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(RandomNumbers.GetRandom(1, 10));
            Console.ReadKey(true);
        }
    }

    static class RandomNumbers
    {
        private static Random random = new Random();

        public static int GetRandom(int min, int max)
        {
            return random.Next(min, max + 1);
        }
    }
}
```

Because we are only using one `Random` object in our application, the sequence of numbers should not repeat (at least there are statistically very low chances of that happening).

One last thing you will notice is that when calling the `Next` method in `GetRandom`, I increased the `maxValue` parameter by one: `random.Next(min, max + 1)`. This is because the `minValue` argument that the function takes is _inclusive_, but the `maxValue` argument is _exclusive_. So for the function to ever return the max value we provided, we have to add 1 to the parameter.

One last thing to point out is that, while the `Random` class is sufficient for most practical reasons, if you want to generate cryptographically strong random sequences, you'll probably want to use the [RandomNumberGenerator class](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator?view=netcore-3.1). The sequences produced by this class are much less predictable, and thus more secure.

Now you can go and do something random! Thanks for reading!

Cover photo from [Unsplash](https://unsplash.com/photos/a6N685qLsHQ) :heart: