如何在C#类的构造函数中生成随机数
我知道在 C# 类的构造函数中调用方法不是一个好习惯,但我坚持了一些奇怪的做法。我的问题是,当我创建类的对象时,我需要用随机数在对象中分配一个字段。
例如
class RandomNumberHandler
{
private int randomNumber;
public RandomNumberHandler()
{
this.randomNumber = GenerateRandomNumber();
}
private int GenerateRandomNumber()
{
return (new Random()).Next(3000) + 1000;
}
}
,就我而言,我需要一个四位数的号码。我想过在创建对象的类中生成随机数并将其作为参数传递给构造函数,但在另一个类中生成随机数似乎也不是一个好主意,因为我试图实现强大的内聚力为了我的课程。我正在为我的大学的“高质量代码”课程这样做,我正在寻找最好的方法。欢迎任何关于如何做到这一点的想法:)
I know that it is not a good practice to call a method in the constructor of a class in C# but I stuck on something strange. My problem is that when I create an object of my class I need to assign a field in my object with a random number.
for instance
class RandomNumberHandler
{
private int randomNumber;
public RandomNumberHandler()
{
this.randomNumber = GenerateRandomNumber();
}
private int GenerateRandomNumber()
{
return (new Random()).Next(3000) + 1000;
}
}
In my case I need a four digit number. I thought of generating the random number in the class where I am creating the object and passing it as a parameter to the constructor but generating a random number in the other class does not seem a very good idea either because I am trying to achieve strong cohesion for my classes. I am doing this for a "High quality code" course in my university and I am looking for the best approach. Any ideas how to do this are welcome :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先:在构造函数中调用非虚拟方法没有任何问题。你从哪里读到有这个? (注意:调用虚拟方法可能是一个问题;这不是自动禁止的,但您需要非常仔细地观察您正在做的事情)。
顺便说一句,每次调用
GenerateRandomNumber
时生成一个新的Random
实例似乎很浪费。您可以将Random
实例提取到一个字段来解决这个问题:但这会引发另一个问题:如果
GenerateRandomNumber
在每个实例的生命周期中(在构造函数中)仅调用一次,那么为每个对象创建一个新的Random
是没有意义的。因此,下一个逻辑步骤是使随机
成为静态
。这意味着GenerateRandomNumber
也可以变成static
(事实上,它必须如此):First off: there is nothing wrong with calling non-virtual methods in the constructor. Where did you read that there was? (Note: calling virtual methods can be a problem; it is not an automatic no-no, but you need to watch what you are doing very carefully).
As an aside, it seems wasteful to generate a new
Random
instance every timeGenerateRandomNumber
is called. You can extract theRandom
instance to a field to fix that:But this raises another question: if
GenerateRandomNumber
is only called once in each instance's lifetime (in the constructor), then it doesn't make sense to create a newRandom
for each object. So the next logical step is to makerandom
bestatic
. This means thatGenerateRandomNumber
can also becomestatic
(and indeed, it has to):该代码可以正常工作 - 但如果您快速连续调用它,您可能会得到“相同”的随机数。
当然,您可以通过使用静态随机数轻松解决这个问题(如果您使用多个线程,则使用锁来保证线程安全),例如:
This code will work okay - except that you'll likely get the "same" random number if you call it in quick succession.
You could, of course, easily work around that by using a static random number (with a lock for thread safety if you're using multiple threads), such as:
随机数生成器仅生成一个随机数
简短回答:您应该在所有
Next()
调用中使用相同的 Random 实例。Random number generator only generating one random number
Short answer: You should use same Random instance across all
Next()
calls.仅将 Random 类包装在另一个名为 RandomHandler 的类中,我看不到任何内聚力。就我个人而言,我认为这很尴尬。如果您需要一个全新的完全随机数,那么只需调用 Random().Next(3000) 或像您所说的构造函数内部的任何内容。
I don't see any cohesion there by just wrapping the Random class inside of another class named RandomHandler. Personally, I think thats awkward. If you need a brand new completely random number then just call Random().Next(3000) or whatever inside of the constructor like you said.
如果将
Random
实例提升为静态字段并使GenerateRandomNumber
静态,则可以在randomNumber
字段的声明中调用它:或者更简单(可读性较差):
虽然看起来您不像在构造函数中调用方法,但如果您查看生成的 CIL,您会发现确实如此。
另外,如果您关心线程安全,请查看此
If you lift the
Random
instance as a static field and make theGenerateRandomNumber
static, you can call it in the declaration of therandomNumber
field:Or more simply (and less readable):
Although it doesn't look like you're calling a method in a constructor, if you look at the generated CIL, you'll find out that you are.
Also, if you care about thread-safety, take a look at this article.