Correct method of a “static” Random.Next in C#?

前端 未结 11 2212
执念已碎
执念已碎 2020-12-10 10:51

Why do i need to create an instance of Random class, if i want to create a random number between 1 and 100 ....like

Random rand = new Random();
rand.Next(1,1         


        
相关标签:
11条回答
  • 2020-12-10 11:06

    You already got answers here. Just reiterating the right solution:

    namespace mySpace
    {
        public static class Util
        {
            private static Random rnd = new Random();
            public static int GetRandom()
            {
                return rnd.Next();
            }
        }
    }
    

    So you can call:

    var i = Util.GetRandom();
    

    all throughout. If you strictly need a true stateless static method to generate random numbers, you can rely on a Guid.

    public static class Util
    {
        public static int GetRandom()
        {
            return Guid.NewGuid().GetHashCode();
        }
    }
    

    It's going to be a wee bit slower, but can be much more random than Random.Next, at least from my experience.

    But not:

    new Random(Guid.NewGuid().GetHashCode()).Next();
    

    The unnecessary object creation is going to make it slower especially under a loop.

    And never:

    new Random().Next();
    

    Not only its slower (inside a loop), it's randomness is... well not really good according to me..

    0 讨论(0)
  • 2020-12-10 11:09

    It's not "unnecessary", because the Random class stores some state internally. It does that to make sure that if you call .Next() multiple times very quickly (in the same millisecond or tick or whatever) you still won't get the same number.

    Of course, if that's not a problem in your case you can always combine those two lines of code into one:

    new Random().Next(1, 100);
    
    0 讨论(0)
  • 2020-12-10 11:09

    The best way to do it is to have a ThreadStatic Random instance:

    [ThreadStatic] static Random random;
    
    Random Get() {
     if (random == null) random = new Random(Guid.NewGuid().GetHashCode());
     return random;
    }
    

    This takes care of everything.

    1. Thread safety
    2. Performance
    3. No need to seed

    It eludes me why the .NET Framework (and any other framework on earth) does not use something in this spirit.

    0 讨论(0)
  • 2020-12-10 11:10

    Creating a new instance of Random then calling it immediately multiple times, e.g.:

    for (int i = 0; i < 1000; i++)
    {
         Random rand = new Random();
         Console.WriteLine(rand.Next(1,100));
    }    
    

    Will give you a distribution that is weighted towards the lower end of the range.

    Doing it this way:

    Random rand = new Random();
    for (int i = 0; i < 1000; i++)
    {
         Console.WriteLine(rand.Next(1,100));
    }    
    

    Will give you a better distribution.

    0 讨论(0)
  • 2020-12-10 11:12

    Random number generators must maintain state in order to be "random." The random number generator creates a sequence that is generated based on a random seed. The problem is that nothing in a computer is actually random. The closest thing the computer has at hand is the system clock; that is the effectively the time at which the process takes place. So by default the current tick count of the system clock is used. If your application is fast enough then many random number calculations may occur under the same system tick. If the random number generator doesn't maintain state at all, it will provide the same random number multiple times (same input gives the same output). This is not usually what you want.

    I know its already answered, but I just have to say that I prefer to use the singleton pattern in this case.

    0 讨论(0)
  • 2020-12-10 11:18

    Creating a short-lived instance in C# is almost free. Don't waste your time worrying about this. You probably have better places to look for perf or memory gains.

    0 讨论(0)
提交回复
热议问题