为什么不必初始化数组中的结构?

时间:2018-07-22 05:56:52

标签: c# arrays unity3d struct

我研究了这个主题,但找不到任何重复的内容。我想知道为什么您可以在数组中使用struct而不创建其实例。

例如,我有一个class和一个struct

public class ClassAPI
{
    public Mesh mesh { get; set; }
}

public struct StructAPI
{
    public Mesh mesh { get; set; }
}

在数组中使用ClassAPI时,必须先使用new关键字对其进行初始化,然后才能使用其属性和方法:

ClassAPI[] cAPI = new ClassAPI[1];
cAPI[0] = new ClassAPI(); //MUST DO THIS!
cAPI[0].mesh = new Mesh();

但是StructAPI并非如此。看来StructAPI不必在数组中初始化:

StructAPI[] sAPI = new StructAPI[1];
sAPI[0].mesh = new Mesh();

如果您使用ClassAPI尝试相同的操作,则会得到NullReferenceException

为什么在数组中使用结构时为什么与结构不同?

我了解classstruct之间的区别,其中struct是一种值类型,但这仍然没有意义。对我来说,如果没有涉及数组,就好像我正在这样做:

StructAPI sp;
sp.mesh = new Mesh();

请注意,sp变量未初始化,它会导致显示以下编译时错误:

  

错误CS0165使用未分配的局部变量'sp'

但是当将struct放入数组中时,情况就不同了。

数组是否在其中初始化struct?我想知道发生了什么。

3 个答案:

答案 0 :(得分:10)

根据PetSerAl在评论中提供的specification link

  

数组元素
  数组的元素在创建数组实例时就存在,而在没有对该数组实例的引用时就不再存在。

     

数组每个元素的初始值为数组元素类型的默认值(Default values)。

     

出于确定分配检查的目的,将数组元素视为初始分配。

(重点是我的)。

这意味着在声明T数组时,将使用default(T)初始化数组中的每个“单元格”。对于引用类型,default(T)返回null,但是对于值类型,default(T)返回类型默认值–数字0,布尔值false,依此类推。

根据Using Structs (C# Programming Guide)页:

  

如果使用默认的无参数构造函数实例化struct对象,则会根据其默认值分配所有成员。

由于结构是值类型,因此default(T)(其中T是结构)会将结构初始化为其默认值,这意味着其所有成员都将被初始化为其默认值– null以供参考类型以及值类型的任何默认值。

因此这行代码StructAPI[] sAPI = new StructAPI[1];基本上创建了一个StructAPI的新数组,其中包含一个单独的StructAPI实例,其实例的mesh属性为default(Mesh)。 / p>

答案 1 :(得分:4)

这很可能是因为类 do 具有默认构造函数,而结构实际上却没有默认构造函数。

为什么需要初始化类数组

类创建对象,然后返回引用。实际变量是对该值的引用。默认值始终为零,因此引用的默认值为null,因为null由全零的地址表示,这意味着它不指向任何内容。

因此,类数组的默认值是所有空引用。

为什么不需要结构数组

另一方面,结构都是按值计算的。它们也没有默认的无参数构造函数,并且C#不允许您创建一个(尽管CLR可以)。由于没有构造函数,CLR可以通过将所有值归零来非常有效地创建结构,而不必调用构造函数。

您可以从this StackOverflow问题中查看有关此原因的更多信息。

答案 2 :(得分:2)

初始化数组时,会将默认值分配给其元素

  • null用于参考类型,
  • 对于值类型,默认值有所不同:对于代表数字的类型,其值为零,对于struct来说,它有点不同,其默认值为struct,所有字段均设置为其默认值。同样,对于引用类型,它是null,对于值类型,它取决于(如上所述)。

因此,基本上,在初始化数组时,struct已初始化(设置为默认值),这就是为什么可以访问它们的属性。