C# 如何在C类的构造函数中生成随机数#
我知道在C#中调用类的构造函数中的方法不是一个好的做法,但我坚持了一些奇怪的观点。我的问题是,当我创建类的对象时,我需要在对象中指定一个带有随机数的字段 比如说C# 如何在C类的构造函数中生成随机数#,c#,methods,random,constructor,C#,Methods,Random,Constructor,我知道在C#中调用类的构造函数中的方法不是一个好的做法,但我坚持了一些奇怪的观点。我的问题是,当我创建类的对象时,我需要在对象中指定一个带有随机数的字段 比如说 class RandomNumberHandler { private int randomNumber; public RandomNumberHandler() { this.randomNumber = GenerateRandomNumber();
class RandomNumberHandler
{
private int randomNumber;
public RandomNumberHandler()
{
this.randomNumber = GenerateRandomNumber();
}
private int GenerateRandomNumber()
{
return (new Random()).Next(3000) + 1000;
}
}
就我而言,我需要一个四位数的号码。我曾想过在创建对象的类中生成随机数,并将其作为参数传递给构造函数,但在另一个类中生成随机数似乎也不是一个好主意,因为我试图实现类的强内聚。我这样做是为了在我的大学里学习“高质量代码”课程,我正在寻找最好的方法。欢迎提出任何方法:)首先:在构造函数中调用非虚方法没有问题。你在哪里读到的?(注意:调用虚拟方法可能是一个问题;这不是一个自动的否定,但您需要非常仔细地观察您正在做什么) 另一方面,每次调用
GenerateRandomNumber
时生成一个新的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
是没有意义的。因此,下一个逻辑步骤是使随机
成为静态
。这意味着GenerateRandomNumber
也可以变成静态的(事实上,它必须):
首先:在构造函数中调用非虚方法没有什么错。你在哪里读到的?(注意:调用虚拟方法可能是一个问题;这不是一个自动的否定,但您需要非常仔细地观察您正在做什么)
另一方面,每次调用GenerateRandomNumber
时生成一个新的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
是没有意义的。因此,下一个逻辑步骤是使随机
成为静态
。这意味着GenerateRandomNumber
也可以变成静态的(事实上,它必须):
简短回答:您应该在所有Next()调用中使用相同的随机实例。
简短回答:您应该在所有Next()
调用中使用相同的随机实例。仅将随机类包装在另一个名为RandomHandler的类中,我看不到任何内聚。我个人认为这很尴尬。如果您需要一个全新的完全随机数,那么只需调用random().Next(3000)或类似于您所说的构造函数内部的任何内容。仅将random类包装在另一个名为RandomHandler的类中,我看不到任何内聚。我个人认为这很尴尬。如果您需要一个全新的完全随机数,那么只需调用random().Next(3000)或您所说的构造函数内部的任何内容。此代码可以正常工作-除非如果您快速连续调用它,您可能会得到“相同”的随机数
当然,您可以通过使用静态随机数(如果使用多个线程,则带有线程安全锁)轻松解决此问题,例如:
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;
}
}
这段代码可以正常工作——只是如果你连续快速调用它,可能会得到“相同”的随机数
当然,您可以通过使用静态随机数(如果使用多个线程,则带有线程安全锁)轻松解决此问题,例如:
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;
}
}
如果将Random
实例提升为静态字段,并使GenerateRandomNumber
静态,则可以在randomname
字段的声明中调用它:
class RandomNumberHandler {
private static Random random = new Random();
private int randomNumber = GenerateRandomNumber();
private static int GenerateRandomNumber() {
return random.Next(3000) + 1000;
}
}
或者更简单(可读性较差):
尽管看起来不像是在构造函数中调用方法,但如果查看生成的CIL,您会发现您是
另外,如果您关心线程安全,请看一看。如果您将随机
实例提升为静态字段,并使GeneratorAndomNumber
静态,则可以在随机数
字段的声明中调用它:
class RandomNumberHandler {
private static Random random = new Random();
private int randomNumber = GenerateRandomNumber();
private static int GenerateRandomNumber() {
return random.Next(3000) + 1000;
}
}
或者更简单(可读性较差):
尽管看起来不像是在构造函数中调用方法,但如果查看生成的CIL,您会发现您是
此外,如果您关心线程安全,请查看此信息。谁知道。。。这些老师总是要把他们的观点强加给学生。我总是按照等级的流程来做。不过在构造函数中调用虚拟方法有一些考虑。可能他对虚拟方法感到困惑。@Kirk,@Eric:当然。但关键是让OP用他自己的话来表达,这样他就可以提高自己的理解力。@Jon,也许吧。但是这句话(黑体字)让我觉得“在构造函数中调用方法没有错”是错误的,或者说是不完整的。谁知道呢。。。这些老师总是要把他们的观点强加给学生。我总是按照等级的流程来做。不过在构造函数中调用虚拟方法有一些考虑。可能他对虚拟方法感到困惑。@Kirk,@Eric:当然。但关键是让OP用他自己的话来表达,这样他就可以提高自己的理解力。@Jon,也许吧。但这句话(粗体字)让我觉得“在构造函数中调用方法没有错”,或者说是错的