1

我的程序有点问题。

我在我的程序中创建了一个这样的类:

class ClassA
{
    public int number = -1;

    public Random rnd = new Random();
    public void randomize()
    {
         var random = rnd;
         number = rnd.next(4)+2;
    }

}

我要创建一个数组,其中每个数组都包含一个类,我是这样创建的。我将数组转移到一个新方法,以便检查它。

public static void Main()
{
    ClassA[,] arrayOfClass = new Class[6,6];
    ClassA classA= new Class();
    int i, j;
    for (i = 0; i < 6; i++)
    {
         for (j = 0; j < 6; j++)
         {

              classA.randomize();

              arrayOfClass[i, j] = classA;
         }
    }
    CheckClassA(arrayOfClass);
}
private void CheckClassA(ClassA[,] arrayOfClass)
{
     int i,j;
     for(i=0;i<6;i++)
     {
         for (j = 0; j < 6; j++)
         {
         Console.Writeline("Randoming : "+arrayOfClass[i,j].number);
         {
     }
}

当我运行这些时,控制台只会一遍又一遍地产生相同的数字,但每次运行都不同,就像它只随机化一次然后再也不会随机化它。

我的问题是: 1. 为什么我的程序只随机化一次并在数组的所有值上返回相同的数字?2. 是不是我的数组传输方法不对?

我尝试使用下面的其他类型来检查我的随机化是否失败,但不是因为它返回了我预期的随机数。

    public static void Main()
    {
        ClassA[,] arrayOfClass = new Class[6,6];
        ClassA class= new Class();
        int i, j;
        for (i = 0; i < 6; i++)
        {
             for (j = 0; j < 6; j++)
             {

                  class.randomize();

                  arrayOfClass[i, j] = class;
                  Console.Writeline("Randoming : " + arrayOfClass[i,j].number);
             }
        }
    }

任何建议和帮助都会受到重视。谢谢

4

3 回答 3

2

这个问题是因为您实际上并没有创建新ClassA对象,您只是对每个数组索引使用相同的对象。ClassA您在某些地方似乎也拼错了Class,我不确定它是如何编译的。将您的 Class 初始化移动到您分配给的循环中arrayOfClass

public static void Main()
{
    ClassA[,] arrayOfClass = new ClassA[6,6];
    //ClassA classA= new Class();
    int i, j;
    for (i = 0; i < 6; i++)
    {
        for (j = 0; j < 6; j++)
        {
            classA = new ClassA();
            classA.randomize();
            arrayOfClass[i, j] = classA;
        }
    }
    CheckClassA(arrayOfClass);
}

完成此操作后,您将遇到另一个问题,它们都出于非常不同的原因返回相同的数字。


它产生相同的数字,因为每个 ClassA 都是在非常接近的时间段内创建的,并且Random使用相同的种子进行初始化。

这是来自 MSDN 上的Random()默认构造函数页面:

默认种子值来自系统时钟并且具有有限的分辨率。因此,通过调用默认构造函数连续创建的不同 Random 对象将具有相同的默认种子值,因此将产生相同的随机数集。这个问题可以通过使用单个 Random 对象来生成所有随机数来避免。您还可以通过修改系统时钟返回的种子值,然后将这个新的种子值显式提供给 Random(Int32) 构造函数来解决此问题。有关详细信息,请参阅 Random(Int32) 构造函数。

所以基本上是因为Random它是伪随机的,它是由一个基于系统时钟的数字初始化的。Random解决此问题的最佳方法是在 的所有实例之间共享相同的对象ClassA,方法是创建它static或将Randomin 的实例传递给randomize方法。

这应该可以解决问题(使它static):

class ClassA
{
    public int number = -1;

    public static Random rnd = new Random();
    public void randomize()
    {
         var random = rnd;
         number = rnd.next(4)+2;
    }

}
于 2013-03-31T18:36:35.800 回答
0

使随机对象成为静态对象,因此类的每个实例都引用它。

这是因为 C# 使用伪随机算法,其中每个下一个值都以某种方式依赖于前一个值。

对于 Random 类的无参数实例化,默认情况下它使用当前时钟值,因此您的类的每个实例都会创建具有相同起始值的 Random 对象,并向它们调用 Next() 返回相同的值,而不是将该值用于另一个 Next()这些值也是相同的。

于 2013-03-31T18:39:32.107 回答
0

您遇到的真正问题是,对于每个条目,您的数组始终设置为相同的对象。每次迭代时都需要new创建一个新的 ClassA,否则只会指向最后一个 .number。

当然,这是对“每次都会使用新的 Random()”的补充,您应该像这样将其设为静态:

public static void Main()
{
        ClassA[,] arrayOfClass = new ClassA[6,6];
        ClassA classA;
        int i, j;
        for (i = 0; i < 6; i++)
        {
                for (j = 0; j < 6; j++)
                {
                    classA = new ClassA(); // MISSING THIS LINE CAUSED ARRAY TO ONLY HAVE LAST ENTRY
                    classA.randomize();

                    arrayOfClass[i, j] = classA;
                }
        }
        CheckClassA(arrayOfClass);
        Console.ReadLine();
    }
    private static void CheckClassA(ClassA[,] arrayOfClass)
    {
            int i,j;
            for(i=0;i<6;i++)
            {
                for (j = 0; j < 6; j++)
                {
                    Console.WriteLine("Randoming : " + arrayOfClass[i, j].number);
                }
            }
    }

     public class ClassA
     {
         public int number = -1;

         public static Random rnd = new Random();
         public void randomize()
         {
             number = rnd.Next(4) + 2;
         }

     }
}
于 2013-03-31T18:40:11.130 回答