“a”的正确方法;“静态”;随机。下一个是C#?

“a”的正确方法;“静态”;随机。下一个是C#?,c#,random,C#,Random,如果我想创建一个介于1和100之间的随机数,为什么我需要创建Random类的实例 Random rand = new Random(); rand.Next(1,100); 有没有随机类的静态函数可以做同样的事情?像 Random.Next(1,100); 我不想不必要地创建一个实例在C#中创建一个短期实例几乎是免费的。不要浪费时间担心这件事。您可能有更好的位置来查找性能或内存增益。最佳做法是创建一个Random的实例,并在整个程序中使用它,否则结果可能不是随机的。不创建静态函数会鼓励这种行

如果我想创建一个介于1和100之间的随机数,为什么我需要创建Random类的实例

Random rand = new Random();
rand.Next(1,100);
有没有随机类的静态函数可以做同样的事情?像

Random.Next(1,100);

我不想不必要地创建一个实例

在C#中创建一个短期实例几乎是免费的。不要浪费时间担心这件事。您可能有更好的位置来查找性能或内存增益。

最佳做法是创建一个
Random
的实例,并在整个程序中使用它,否则结果可能不是随机的。不创建静态函数会鼓励这种行为

您不必担心“不必要地创建实例”,其影响最多可以忽略不计-这是框架的工作方式。

这不是“不必要的”,因为Random类在内部存储一些状态。它这样做是为了确保如果您快速多次调用
.Next()
(在相同的毫秒或滴答声或其他时间内),您仍然不会得到相同的号码

当然,如果这在您的案例中不是问题,您可以始终将这两行代码合并为一行:

new Random().Next(1, 100);
为什么不呢

您需要创建一个实例,因为生成随机数的方式是先前的答案会影响后续的答案。默认情况下,
new Random()
构造函数使用当前系统时间“播种”序列,但不必这样做:如果愿意,您可以传入自己的数字。特别是:

var rand = new Random(1234);
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
每次都会产生相同的“随机”数序列

这意味着,
Random
类需要为后续调用保留实例数据(上一个答案,或“种子”)。

来自:

“随机数生成从种子值开始。如果重复使用同一种子,则生成相同的数字序列。产生不同序列的一种方法是使种子值与时间相关,从而产生一个不同的序列,每个新的随机序列实例默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值,而其参数化构造函数可以根据当前时间的节拍数获取Int32值但是,由于时钟分辨率有限,因此使用无参数构造函数连续创建不同的随机对象会创建生成相同随机数序列的随机数生成器。以下示例说明了两个连续实例化的随机对象会生成一系列相同的随机数…”


创建Random的新实例,然后立即调用它多次,例如:

for (int i = 0; i < 1000; i++)
{
     Random rand = new Random();
     Console.WriteLine(rand.Next(1,100));
}    
for(int i=0;i<1000;i++)
{
Random rand=新的Random();
控制台写入线(兰特下一代(1100));
}    
将为您提供一个向范围低端加权的分布

这样做:

Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
     Console.WriteLine(rand.Next(1,100));
}    
Random rand=new Random();
对于(int i=0;i<1000;i++)
{
控制台写入线(兰特下一代(1100));
}    

将为您提供更好的分发版。

如果您希望使用您提到的语法,则需要类似的内容

namespace MyRandom
{
    public class Random
    {
        private static m_rand = new Random();
        public static Next(int min, int max)
        {
            return m_rand.Next(min, max);
        }
    }
}

这应该允许您执行随机。下一步(1100);而不必担心种子设定。

随机数生成器必须保持状态才能成为“随机”。“随机数生成器创建基于随机种子生成的序列。问题是计算机中没有任何东西是随机的。计算机手头最接近的东西是系统时钟;这是该过程发生的有效时间。因此,默认情况下使用系统时钟的当前滴答计数。如果您的应用程序足够快,那么在同一系统下可能会发生许多随机数计算。如果随机数生成器根本不保持状态,它将多次提供相同的随机数(相同的输入产生相同的输出)。这通常不是你想要的


我知道它已经得到了回答,但我不得不说,在这种情况下,我更喜欢使用单例模式

这里已经有答案了。只需重申正确的解决方案:

namespace mySpace
{
    public static class Util
    {
        private static Random rnd = new Random();
        public static int GetRandom()
        {
            return rnd.Next();
        }
    }
}
new Random(Guid.NewGuid().GetHashCode()).Next();
new Random().Next();
所以你可以打电话:

var i = Util.GetRandom();
自始至终如果您严格地需要一个真正的无状态静态方法来生成随机数,您可以依赖
Guid

public static class Util
{
    public static int GetRandom()
    {
        return Guid.NewGuid().GetHashCode();
    }
}
它会稍微慢一点,但可能比随机的要随机得多。下一步,至少从我的经验来看

但是不是

namespace mySpace
{
    public static class Util
    {
        private static Random rnd = new Random();
        public static int GetRandom()
        {
            return rnd.Next();
        }
    }
}
new Random(Guid.NewGuid().GetHashCode()).Next();
new Random().Next();
不必要的对象创建将使其速度变慢,尤其是在循环下

从不

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

不仅它的速度慢(在一个循环中),它的随机性是。。。根据我的说法,这不是很好。

最好的方法是使用
ThreadStatic
Random
实例:

[ThreadStatic] static Random random;

Random Get() {
 if (random == null) random = new Random(Guid.NewGuid().GetHashCode());
 return random;
}
这会照顾好一切

  • 线程安全
  • 演出
  • 不需要播种

  • 我不明白为什么.NET Framework(以及地球上的任何其他框架)不本着这种精神使用某些东西。

    像这样使用Random很可能是个问题……如果不是,它可能很快就会成为一个问题-如果有人实现这样的随机数生成器,因为它每50毫秒调用一次,并且可以正常工作,一旦硬件速度加快,它会很快崩溃,有人会花很多时间调试:)是的,所以我从来不会在循环中使用这种代码-但是如果你知道你的程序只需要生成一个随机数,那么它就足够安全了。是的,用它来获取单个项目。从来没有别的。试图否决投票。最后。。。不要过早地优化:-)如果随机是静态的,可能无法实现的复制?发电机将在施工时播种,您可以使用i