Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# System.Random extensions

0.00/5 (No votes)
29 Jul 2016 1  
A library of simple extension methods that could be useful for data generation tasks

Introduction

When starting to work on a new project that is supposed to use a lot of data, it is probable that the data itself doesn't exist yet. On the development stage, though, some data is required for testing purposes. Of course, there always is an option to manually add some virtual data, but a true developer tends to assign such a work to a computer. Thus raises the task of data generation.

If we talk about a C# project, data generation means usage of System.Random class, which is appropriate, but unfortunately lacks some useful feachures. I've tried to improve the situation a little and wrote a bunch of extension methods that could come in handy.

Using the code

Besides the library itself, the source also contains a working example with comments provided.

Here are some [edited] code snippets:

Date generating

There is a NextDate method which is used like a standard Next method of a Random class, but it returns DateTime object instead of integers:

Random _random = new Random();
// Date of birth is a date between 1/1/1800 and a day that was 25 years ago
DateTime birthFrom = new DateTime(1800, 1, 1);
DateTime birthTo = DateTime.Now.AddYears(-25);
DateTime birthDate = _random.NextDate(birthFrom, birthTo);

Range limits could be omitted. Note that the Time part of a DateTime variable is being nullified here; but there is also a NextDateTime method. And a NextLong method, which they both are based on.

Choosing random item from an array

Yes, it is not very difficult to choose a random item from a list/array using a Next method of Random class, but the following code is a little bit cleaner:

Random _random = new Random();
string[] _lastNames = { "Johnson", "King", "Verne", "Hawk", "Sterling", "Stout", "Webster", "Knight", "Aston", "Anderson" };
string lastName = _random.NextItem(_lastNames);

Using probability checks

Once again, it is achievable with standard methods, but this code is shorter and pretty clear.

Random _random = new Random();
string[] _firstNames = { "John", "Rex", "Andrew", "Jonathan", "Stephen", "Frederick", "Louis", "Matthew" };
string middleName = null;

// ...

// 1/3 persons to have a middle name
if (_random.HitBullsEye(3))
{
    // in 3 of 10 cases middle name is just a letter (like Jerome K. Jerome)
    middleName = _random.IsTrueWithProbability(0.3)
        ? $"{(char)('A' + _random.Next(0, 26))}."
        : _random.NextItem(_firstNames);
}

Note that HitBullsEye method virtually throws a dart at the shooting target (which, in this case, consist of 3 circles) and returns true only when hits a target's bull's-eye.

But if you like, you could throw a virtual dice instead, like this:

// 1/2 males, 1/2 females
Person.PersonSex sex = _random.ThrowDiceToHit(2, 2) ? Person.PersonSex.Male : Person.PersonSex.Female;

(In ThrowDiceToHit method, first parameter is a number of dice sides and the second is the lowest "win" value. Thus, ThrowDiceToHit(6, 3) returns true only if the uppermost side of the dice shows number from 3 to 6, i.e. in 2/3 of cases.)

Additionally, you could combine a probability check with choosing a list item:

// Females could have a maiden name...
if (sex == Person.PersonSex.Female)
{
    // ... in 7 of 10 cases
    maidenName = _random.NextItemOrDefault(_lastNames, 0.7);
}

Points of Interest

Since these methods are based on the standard Next and NextDouble methods of System.Random class, I would not use them in tasks that requires security or strong reliability. (I am not even sure that NextLong method would cover all the long values of the long-sized ranges.) But they suit pretty well for test data generators. Also, I think, the throwing dice part could be useful in games.

History

This is the first version of the article. I will try to update it in case of changes in the library. But you always could get the latest version of the code on GitHub.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here