如何在C#中的类的构造函数中生成随机数

我知道在C#中的类的构造函数中调用一个方法不是一个好习惯,但我坚持一些奇怪的东西。 我的问题是,当我创建一个类的对象时,我需要在对象中使用随机数分配一个字段。

例如

class RandomNumberHandler { private int randomNumber; public RandomNumberHandler() { this.randomNumber = GenerateRandomNumber(); } private int GenerateRandomNumber() { return (new Random()).Next(3000) + 1000; } } 

在我的情况下,我需要一个四位数字。 我想在我创建对象的类中生成随机数并将其作为参数传递给构造函数,但在另一个类中生成随机数似乎不是一个好主意,因为我试图实现强大的凝聚力对于我的课程。 我正在为我在大学的“高质量代码”课程这样做,我正在寻找最好的方法。 欢迎任何想法如何做到这一点:)

首先: 在构造函数中调用非虚方法没有任何问题 。 你在哪里读到的? (注意:调用虚拟方法可能是一个问题;它不是一个自动禁止,但你需要非常仔细地观察你正在做的事情)。

另外,每次调用GenerateRandomNumberGenerateRandomNumber一个新的Random实例似乎都很浪费。 您可以将Random实例提取到字段以修复该问题:

 class RandomNumberHandler { private readonly Random random = new Random(); private int randomNumber; public RandomNumberHandler() { this.randomNumber = GenerateRandomNumber(); } private int GenerateRandomNumber() { return this.random.Next(3000) + 1000; } } 

但是这引出了另一个问题:如果GenerateRandomNumber仅在每个实例的生命周期中被调用一次(在构造函数中),那么为每个对象创建一个新的Random是没有意义的。 因此,下一个合乎逻辑的步骤是使random变为static 。 这意味着GenerateRandomNumber也可以变为static (事实上​​,它必须):

 class RandomNumberHandler { private static readonly Random Random = new Random(); private int randomNumber; public RandomNumberHandler() { this.randomNumber = GenerateRandomNumber(); } private static int GenerateRandomNumber() { return Random.Next(3000) + 1000; } } 

这段代码可以正常工作 – 除非您快速连续调用它,否则您可能会获得“相同”的随机数。

当然,您可以通过使用静态随机数(如果您使用多个线程具有锁定线程安全性)轻松解决此问题,例如:

 class RandomNumberHandler { private static Random random = new Random(); private static object syncObj = new object(); private int randomNumber; public RandomNumberHandler() { this.randomNumber = GenerateRandomNumber(); } private static int GenerateRandomNumber() { lock(syncObj) return random.Next(3000) + 1000; } } 

随机数生成器仅生成一个随机数

简短回答:您应该在所有Next()调用中使用相同的Random实例。

我没有看到任何凝聚力只是将Random类包装在另一个名为RandomHandler的类中。 我个人认为这很尴尬。 如果你需要一个全新的完全随机数,那么只需调用Random()。Next(3000)或者你所说的构造函数内部的任何内容。

如果将Random实例作为静态字段提起并使GenerateRandomNumber静态,则可以在randomNumber字段的声明中调用它:

 class RandomNumberHandler { private static Random random = new Random(); private int randomNumber = GenerateRandomNumber(); private static int GenerateRandomNumber() { return random.Next(3000) + 1000; } } 

或者更简单(并且不太可读):

 class RandomNumberHandler { private static Random random = new Random(); private int randomNumber = random.Next(3000) + 1000; } 

虽然看起来你不是在构造函数中调用方法,但是如果你看一下生成的CIL,你会发现你是。

另外,如果您关心线程安全,请查看本文 。