-1

I have a static method in a static class which can generate random strings, like this:

public static class DataGenerator
    {
        public static string GenerateRandomString(int length)
        {
            const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var random = new Random();
            return new string(
                Enumerable.Repeat(Chars, length)
                    .Select(s => s[random.Next(s.Length)])
                    .ToArray());
        }
}

When I call this method multiple times from the same calling function, it seems to cache the generated string.

Here is an example of usage:

var item = new CodeDescActivePo()
                {
                    Active = true, 
                    Code = DataGenerator.GenerateRandomString(10), 
                    Description = DataGenerator.GenerateRandomString(10)
                };

Notice that there are 2 calls to GenerateRandomString, I would expect 2 unique random numbers, in this case Code and Description are always the same.

Why would GenerateRandomString not generate a fresh random number each time?

gturri
  • 13,807
  • 9
  • 40
  • 57
JL.
  • 78,954
  • 126
  • 311
  • 459
  • Random is created with the same seed? – Sayse Jul 15 '14 at 08:58
  • 2
    var random = new Random(); is wrong. You should initialize only once, then use it forever. If you new it every time, it could generate same values. – Oğuz Sezer Jul 15 '14 at 08:58
  • 1
    I don't know who voted to reopen, but if you want a static-specific duplicate see [Random number generator only generating one random number](http://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number). This question is not unique. – CodeCaster Jul 15 '14 at 09:03
  • 1
    Even if there was no static-specific answer, this would still be a duplicate. The two issues are fundamentally the same, and the answer applies to both. – dcastro Jul 15 '14 at 09:10
  • Just an observation. If you want random strings have you considered Membership.GeneratePassword, Path.GetRandomFileName. Although maybe that's a bit hacky. – Nathan Cooper Jul 15 '14 at 09:16

3 Answers3

10

You are calling var random = new Random(); too quickly together. Since the default seed is time based, the seed is the same. Better to create this variable once and Random.Next() every time you need it.

public static class DataGenerator
{
    private readonly static Random random = new Random();

    public static string GenerateRandomString(int length)
    {
       //etc etc using random.Next()
    }
}
Jeffrey Blake
  • 9,659
  • 6
  • 43
  • 65
Nathan Cooper
  • 6,262
  • 4
  • 36
  • 75
1

Because you are using a new Random() instance for each call. By default it is seeded with the current system time, which means that multiple Random instances created at the same time will give the same values.

Make the Random instance a static field instead to keep it alive between the calls.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
0

Problem:

From MSDN

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.

Solution: Again from MSDN

This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • The example they give uses `Thread.Sleep` to demonstrate how the default constructor works. In actually code, this is not one of the few legitimate uses of `Thread.Sleep` and should be avoided. – Nathan Cooper Jul 15 '14 at 09:06
  • @NathanCooper: That's why I have provided another solution. – Nikhil Agrawal Jul 15 '14 at 09:07
  • Thanks for responding to my comment, I'm glad you agree. I just wanted to make sure the OP didn't get the wrong idea. – Nathan Cooper Jul 15 '14 at 09:10