C# 为什么数组中的每个元素都要在c中重新分配#

C# 为什么数组中的每个元素都要在c中重新分配#,c#,c++,.net,memory-management,console-application,C#,C++,.net,Memory Management,Console Application,下面是我编写的代码 Calc[]计算器=新的计算器[10] 计算器[0].AddToSum(10)(编写了相应的类和方法)。 但是我得到了“Object reference not set to a instance of a Object”(对象引用未设置为对象实例)异常 for (int i = 0; i < 10; i++) { calculators[i] = new Calc(); } 我认为您不会再次分配内存,但仍然

下面是我编写的代码
Calc[]计算器=新的计算器[10]
计算器[0].AddToSum(10)(编写了相应的类和方法)。
但是我得到了“Object reference not set to a instance of a Object”(对象引用未设置为对象实例)异常

for (int i = 0; i < 10; i++)
        {
            calculators[i] = new Calc();
        }  

我认为您不会再次分配内存,但仍然需要为
计算器[0]
实例化一些值

在您的第一个代码段中,您正试图调用
.AddToSum
,调用的值为
Null

Ps:您可以执行以下操作,从一开始就初始化每个
Calc

更新:回应以下评论;好的,那么试试这个:

calc[] calculators = Enumerable.Repeat(new Calc(), 127).ToArray<Calc>();
calc[]calculators=可枚举。重复(新的calc(),127)。ToArray();

我认为您不会再次分配内存,但仍然需要为
计算器[0]
实例化一些值

在您的第一个代码段中,您正试图调用
.AddToSum
,调用的值为
Null

Ps:您可以执行以下操作,从一开始就初始化每个
Calc

更新:回应以下评论;好的,那么试试这个:

calc[] calculators = Enumerable.Repeat(new Calc(), 127).ToArray<Calc>();
calc[]calculators=可枚举。重复(新的calc(),127)。ToArray();

在新计算[10]中,您正在分配阵列并调整其大小。在new Calc()中,您正在创建实际的Calc对象。在new Calc[10]中,您正在分配和调整数组的大小。在new Calc()中,您正在创建实际的Calc对象,但此语句也会出现相同的错误

Calc calc; 
calc.AddToSum(10);
在赋值之前,对象为空

计算[]计算器=新计算[10];不分配

根据Benjamin(+1)的回答,如果Calc是一种参考类型,则它是有效的。

你能把Calc变成一个结构吗

但是这个语句也会出现同样的错误

Calc calc; 
calc.AddToSum(10);
在赋值之前,对象为空

计算[]计算器=新计算[10];不分配

根据Benjamin(+1)的回答,如果Calc是一种参考类型,则它是有效的。

你能把Calc变成一个结构吗 另一方面,在c#中,当创建一个正在创建的对象数组和一个引用数组(指向对象的指针)时。因此,除非为每个引用分配内存(使用new),否则无法存储实例


C++中的相同的事情是生成指针数组,然后你必须实例化数组的每个元素。

< P>当你在C++中创建一个对象数组时,你为每个对象的所有字段分配内存。因此,如果您的对象有两个整数字段,并且您创建了一个大小为2的数组,那么将分配足够的内存来容纳四个整数

另一方面,在c#中,当创建一个正在创建的对象数组和一个引用数组(指向对象的指针)时。因此,除非为每个引用分配内存(使用new),否则无法存储实例

C++中同样的事情是做一个指针数组,然后你必须实例化数组中的每个元素。

在C中,有引用类型,并且有值类型。类是引用类型。创建引用类型的变量时,创建的是引用,而不是对象。引用的默认状态为null。如果希望它引用一个对象,则必须使用
new
显式初始化它,或者从另一个初始化的引用中指定If

C++没有这种区别。每个类型都是值类型(尽管您也可以创建对任何类型的引用)。当您创建值类型的变量时,您正在创建一个对象。

在C#中,有引用类型,也有值类型。类是引用类型。创建引用类型的变量时,创建的是引用,而不是对象。引用的默认状态为null。如果希望它引用一个对象,则必须使用
new
显式初始化它,或者从另一个初始化的引用中指定If


C++没有这种区别。每个类型都是值类型(尽管您也可以创建对任何类型的引用)。当你创建一个值类型的变量时,你正在创建一个对象。

你的C++代码也是错误的。 在C++中,您已经为10个计算器对象分配了一个空间。 当您执行该操作时,它将从(未初始化的)内存中读取、获取一个值并将其添加,然后将其写回。 但您有一个未初始化的对象要从中开始

它可能在C++中工作,因为你有一个对象(计算器)不需要调用构造函数。如果它有任何需要调用构造函数的初始化,它将无法工作。如果您使用调试器并在计算器构造函数中放置断点,您将看到它从未被调用

无论如何,要直接回答这个问题,这就是C#的工作方式。分配数组会为数组创建空间,但数组中的所有对象(假定对象类型)在分配它们自己之前都是空的


可以这样想:我创建了一个数组来容纳10个类X的对象。但是X有一个构造函数,它接受一个字符串,我想为每个对象调用一个不同的字符串。如果不显式地创建这10个对象中的每一个,并将正确的字符串传递给每个构造函数,那么如何做到?

< p>您的C++代码也是错误的。 在C++中,您已经为10个计算器对象分配了一个空间。 当您执行该操作时,它将从(未初始化的)内存中读取、获取一个值并将其添加,然后将其写回。