TOC

This article is currently in the process of being translated into Chinese (~88% done).

Misc:

Randomness with the Random class

程序的运行有时需要随机性。有很多原因 - 可能需要以随机顺序对列表排序(随机播放)或制作游戏时需要让组件往随机的方向移动。不管什么原因,都需要有办法从计算机中获得一个随机值,幸好,C#可以提供帮助。

多数情况下,可以由Random类开始,此类可以生成一个或多个特定范围内的随机数。而且此类的使用非常简单:

Random random = new Random();
Console.WriteLine("A random number: " + random.Next());

这里初始化了一个新的Random类实例,然后调用其Next()方法获得一个随机数(整数) - 很简单!

如果需要的是小数而不是整数,可以改用NextDouble()方法 - 这会返回一个介于0.0(包含此值)和0.99(即任何小于1.0的数字)之间的数字:

Random random = new Random();
Console.WriteLine("A random number with decimals: " + random.NextDouble());

随机范围

多数情况需要的不是任何随机数 - 而是某种范围内的随机数,比如,1到100之间。别担心,用Random很容易实现:

Random random = new Random();
Console.WriteLine("A random number between 1 and 100: " + random.Next(1, 101));

上例只简单把Next()方法调用改为包含最小值和最大值参数的调用。注意其中最小值是包容性的(即此值包括在可能的输出值范围内),而最大值是非包容性的(即此值不包括在可能的输出值范围内),所以使用了101而非100。如果想要的值是0到99,可以象这样改写:

Console.WriteLine("A random number between 0 and 99: " + random.Next(0, 100));

Random类种子

Random类初始化时都需要一个种子,或是明确提供,或是由.NET framework暗中提供。此种子允许控制其随机性 - 多次使用同一个种子可以生成同一组随机数。这听起来很奇怪,但在测试程序/游戏等的特定场景时很有用。

种子通过构造器重载传递,象这样:

Random random = new Random(1000);

来看看用此实例连续生成5个随机数怎么样:

Random random = new Random(1000);
for(int i = 0; i < 5; i++)
	Console.WriteLine("A random number between 1 and 100: " + random.Next(1, 101));

不管运行此代码多少次,得到的5个“随机”数永远都会是这样:

A random number between 1 and 100: 16
A random number between 1 and 100: 24
A random number between 1 and 100: 76
A random number between 1 and 100: 1
A random number between 1 and 100: 70

通过此示例可看出,由Random类生成的随机数并不那么随机。而是使用种子值生成的伪随机数。因此,当编程者不提供种子时,.NET framework会自动提供一个。在最初的.NET framework版本中,使用的是当前时间,而后面的.NET core framework使用的是线程独立的伪随机数生成器来产生随机数。换言之,除非需要控制随机性,都应该使用默认的Random类构造器,象第一个例子那样。

总结

使用Random类生成随机数,不过除非想得到可预测的随机,否则应该使用随机种子 - .NET framework会自动处理,除非通过构造器重载传入随机种子。

还需注意一点,初始化Random类有点耗资源,因此不要在循环中反复生成新的Random类实例 - 而是只生成一个Random类实例,用Next()方法来获得任意多的随机数。

最后,如上文所述,Random类是个伪随机数生成器。如果需要更安全的方式,如,加密和/或生成密码,可以使用RNGCryptoServiceProvider类。


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!