C# 类数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15732960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array of Classes
提问by Diom
I'm having a problem with my program a little bit.
我的程序有点问题。
I created a class like this in my programs:
我在我的程序中创建了一个这样的类:
class ClassA
{
public int number = -1;
public Random rnd = new Random();
public void randomize()
{
var random = rnd;
number = rnd.next(4)+2;
}
}
I was going to create and array which each of the array contain a class, which i created like this. I transferring the array to a new method so I can check on it.
我打算创建一个数组,其中每个数组都包含一个类,我是这样创建的。我将数组转移到一个新方法,以便我可以检查它。
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);
{
}
}
When I run these, the console only produce the same number over and over, but different on every run, its like it only randomize it once then never randomize it again.
当我运行这些时,控制台只会一遍又一遍地产生相同的数字,但每次运行都不同,就像它只随机化一次然后再随机化一次。
My Question are: 1. Why my program only randomize once and return the same number on all the value of the array? 2. Does my method of transferring array wrong?
我的问题是: 1. 为什么我的程序只随机化一次并在数组的所有值上返回相同的数字?2. 是不是我传数组的方法不对?
I tried using other type below to check if my randomize failed, but no it didn't because its returning the random number as I expected.
我尝试使用下面的其他类型来检查我的随机化是否失败,但没有失败,因为它按照我的预期返回了随机数。
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);
}
}
}
Any suggestion and help are appriciated. Thanks
任何建议和帮助是appriciated。谢谢
采纳答案by Daniel Imms
The issue is being caused because of the fact that you're not actually creating new ClassA
objects, you're just using the same one to each array index. You also seemed to misspell ClassA
in some places as Class
, I'm not sure how it compiled like it was. Move your Class initialisation into the loop where you're assigning to arrayOfClass
.
这个问题是因为您实际上并没有创建新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);
}
When this is done you will run into another issue of them all returning the same number for a very different reason.
完成此操作后,您将遇到另一个问题,它们都出于非常不同的原因返回相同的数字。
It produces the same number because each ClassA is created within a very close time period and Random
is initialised with the same seed.
它产生相同的数字,因为每个 ClassA 都是在非常接近的时间段内创建的,并Random
使用相同的种子进行初始化。
This is from the Random()default constructor page on MSDN:
这是来自MSDN 上的Random()默认构造函数页面:
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.
默认种子值来自系统时钟并且具有有限分辨率。因此,通过调用默认构造函数连续创建的不同 Random 对象将具有相同的默认种子值,因此将生成相同的随机数集。可以通过使用单个 Random 对象生成所有随机数来避免此问题。您还可以通过修改系统时钟返回的种子值,然后将这个新的种子值显式提供给 Random(Int32) 构造函数来解决这个问题。有关更多信息,请参阅 Random(Int32) 构造函数。
So basically because Random
is pseudo random it's initialised by a number that is based on the system clock. Your best way around this is to share the same Random
object between all instances of ClassA
, either by making it static
or passing an instance of Random
in to the randomize
method.
所以基本上是因为Random
它是伪随机的,它是由一个基于系统时钟的数字初始化的。解决此问题的最佳方法是Random
在 的所有实例之间共享相同的对象ClassA
,方法是创建它static
或将Random
in的实例传递给randomize
方法。
This should fix the problem (making it static
):
这应该可以解决问题(制作它static
):
class ClassA
{
public int number = -1;
public static Random rnd = new Random();
public void randomize()
{
var random = rnd;
number = rnd.next(4)+2;
}
}
回答by Lev
Make random object static, so every instance of class refers to it.
将随机对象设为静态,因此类的每个实例都引用它。
This is because C# uses pseudo random algorithm, where every next value is somehow depended on previous value.
这是因为 C# 使用伪随机算法,其中每个下一个值都以某种方式依赖于前一个值。
For parameterless instantiation of Random class it uses current clock value by default, so every instance of your class creates Random object with the same starting value and calling Next() to them returns the same value, than this value is used for another Next() and those values are same too.
对于 Random 类的无参数实例化,它默认使用当前时钟值,因此您的类的每个实例都创建具有相同起始值的 Random 对象并调用 Next() 返回相同的值,而不是该值用于另一个 Next()这些值也是相同的。
回答by Rob G
The real issue you're having is that your array is always set to the same object, for each entry. You need to new
up a new ClassA every time you iterate through, otherwise you're only going to be pointing to the last .number.
您遇到的真正问题是,对于每个条目,您的数组始终设置为相同的对象。new
每次迭代时都需要创建一个新的 ClassA,否则只会指向最后一个 .number。
Of course, this is in addition to the little 'would be using a new Random() every time', which you should make static like so:
当然,这是对“每次都会使用新的 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;
}
}
}