Click here to Skip to main content
14,640,670 members
Articles » Languages » C# » General
Article
Posted 29 Jul 2016

Tagged as

Stats

11.7K views
248 downloads
19 bookmarked

C# System.Random extensions

Rate this:
5.00 (17 votes)
Please Sign up or sign in to vote.
5.00 (17 votes)
29 Jul 2016CPOL
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Igor Krein
Israel Israel
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pin
Dmitriy Gakh30-Jul-16 4:19
professionalDmitriy Gakh30-Jul-16 4:19 
PraiseGood idea. I like it. Pin
wmjordan29-Jul-16 16:26
professionalwmjordan29-Jul-16 16:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.