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

时间:2022-12-08 07:18:37

I researched this subject but I couldn't find any duplicate. I am wondering why you can use a struct in an array without creating an instance of it.

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

For example, I have a class and a struct:

例如,我有一个类和一个结构:

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

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

When ClassAPI is used in an array, it has to be initialized with the new keyword before being able to use its properties and methods:

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

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

But this is not the case with StructAPI. It looks like StructAPI doesn't have to be initialized in the array:

但是StructAPI不是这种情况。看起来StructAPI不必在数组中初始化:

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

If you try the same thing with ClassAPI, you would get a NullReferenceException.

如果您使用ClassAPI尝试相同的操作,您将获得NullReferenceException。

Why is it different with structs when using them in an array?

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

I understand the difference between class and struct with struct being a value type but that still doesn't make sense. To me, without the array being involved in this, it would look like I am doing this:

我理解class和struct之间的区别,struct是一个值类型,但仍然没有意义。对我来说,没有数组参与其中,看起来我会这样做:

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

Notice that the sp variable is not initialized and it should result in a compile-time error that says:

请注意,sp变量未初始化,并且应该导致编译时错误,该错误表示:

Error CS0165 Use of unassigned local variable 'sp'

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

but that's a different story when the struct is put in an array.

但是当结构放入数组时,这是一个不同的故事。

Is the array initializing the struct in it? I would like to know what's going on.

数组是否正在初始化结构?我想知道发生了什么。

3 个解决方案

#1


10  

As per the specification link provided by PetSerAl in the comments:

根据PetSerAl在评论中提供的规范链接:

Array elements
The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance.

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

The initial value of each of the elements of an array is the default value (Default values) of the type of the array elements.

数组中每个元素的初始值是数组元素类型的默认值(默认值)。

For the purpose of definite assignment checking, an array element is considered initially assigned.

出于明确赋值检查的目的,最初分配数组元素。

(emphasis mine).

(强调我的)。

This means that when you declare an array of T, each "cell" in the array is being initialized using default(T). For reference types default(T) returns null, but for value types default(T) returns the type default value – 0 for numbers, false for bool, and so on.

这意味着当您声明一个T数组时,数组中的每个“单元格”都使用默认值(T)进行初始化。对于引用类型,default(T)返回null,但对于值类型,default(T)返回类型默认值 - 数字为0,bool为false,依此类推。

As per the Using Structs (C# Programming Guide) page:

根据Using Structs(C#编程指南)页面:

If you instantiate a struct object using the default, parameterless constructor, all members are assigned according to their default values.

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

Since structs are value types, default(T) where T is a struct initializes the struct to its default value, meaning all its members will be initialized to their default values – null for reference types and whatever default value for value types.

由于结构是值类型,因此默认(T)(其中T是结构)将结构初始化为其默认值,这意味着其所有成员将初始化为其默认值 - 引用类型为null,值类型为默认值。

So this line of code StructAPI[] sAPI = new StructAPI[1]; basically creates a new array of StructAPI containing a single StructAPI instance, where its mesh property is default(Mesh).

所以这行代码StructAPI [] sAPI = new StructAPI [1];基本上创建一个包含单个StructAPI实例的新StructAPI数组,其mesh属性为default(Mesh)。

#2


4  

This is likely because the fact that classes, while they do have a default constructor, structs actually don't have one.

这很可能是因为类虽然确实有默认构造函数,但实际上没有类。

Why class arrays need to be intialized

Classes create the object and then return the reference. The actual variable is a reference to that value. Default values are always zeros, so the default value to a reference is null, because null is represented by an address of all zeros, meaning its not pointing to anything.

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

Because of this, the default value for the array of a class is all null references.

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

Why struct arrays don't need to be

Structs, on the other hand, are all by value. They also don't have a default parameterless constructor and C# doesn't let you create one (though the CLR does). Because of the fact that there isn't a constructor, the CLR is able to very efficiently create the struct by zeroing out all of the values, without having to call the constructor.

另一方面,结构都是有价值的。它们也没有默认的无参数构造函数,C#不允许您创建一个(尽管CLR会这样做)。由于没有构造函数,CLR能够通过将所有值清零来非常有效地创建结构,而无需调用构造函数。

You can view more about why this is from this * question.

您可以从此*问题中查看有关此原因的详细信息。

#3


2  

When you initialize an array, default values are assigned to its elements:

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

  • null for reference types,
  • null为引用类型,
  • for value types, the default value varies: zero for types representing numbers, for struct it is little bit different, its default value is struct with all fields set to their default values. Again, for reference types it's null and for value types it depends (as mentioned above).
  • 对于值类型,默认值是变化的:对于表示数字的类型为零,对于struct,它有点不同,其默认值为struct,所有字段都设置为其默认值。同样,对于引用类型,它是null,对于它所依赖的值类型(如上所述)。

So, basically, when you initialize array you have your structs initialized (set to default value), that's why you can access their properties.

因此,基本上,当您初始化数组时,您的结构已初始化(设置为默认值),这就是您可以访问其属性的原因。

#1


10  

As per the specification link provided by PetSerAl in the comments:

根据PetSerAl在评论中提供的规范链接:

Array elements
The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance.

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

The initial value of each of the elements of an array is the default value (Default values) of the type of the array elements.

数组中每个元素的初始值是数组元素类型的默认值(默认值)。

For the purpose of definite assignment checking, an array element is considered initially assigned.

出于明确赋值检查的目的,最初分配数组元素。

(emphasis mine).

(强调我的)。

This means that when you declare an array of T, each "cell" in the array is being initialized using default(T). For reference types default(T) returns null, but for value types default(T) returns the type default value – 0 for numbers, false for bool, and so on.

这意味着当您声明一个T数组时,数组中的每个“单元格”都使用默认值(T)进行初始化。对于引用类型,default(T)返回null,但对于值类型,default(T)返回类型默认值 - 数字为0,bool为false,依此类推。

As per the Using Structs (C# Programming Guide) page:

根据Using Structs(C#编程指南)页面:

If you instantiate a struct object using the default, parameterless constructor, all members are assigned according to their default values.

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

Since structs are value types, default(T) where T is a struct initializes the struct to its default value, meaning all its members will be initialized to their default values – null for reference types and whatever default value for value types.

由于结构是值类型,因此默认(T)(其中T是结构)将结构初始化为其默认值,这意味着其所有成员将初始化为其默认值 - 引用类型为null,值类型为默认值。

So this line of code StructAPI[] sAPI = new StructAPI[1]; basically creates a new array of StructAPI containing a single StructAPI instance, where its mesh property is default(Mesh).

所以这行代码StructAPI [] sAPI = new StructAPI [1];基本上创建一个包含单个StructAPI实例的新StructAPI数组,其mesh属性为default(Mesh)。

#2


4  

This is likely because the fact that classes, while they do have a default constructor, structs actually don't have one.

这很可能是因为类虽然确实有默认构造函数,但实际上没有类。

Why class arrays need to be intialized

Classes create the object and then return the reference. The actual variable is a reference to that value. Default values are always zeros, so the default value to a reference is null, because null is represented by an address of all zeros, meaning its not pointing to anything.

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

Because of this, the default value for the array of a class is all null references.

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

Why struct arrays don't need to be

Structs, on the other hand, are all by value. They also don't have a default parameterless constructor and C# doesn't let you create one (though the CLR does). Because of the fact that there isn't a constructor, the CLR is able to very efficiently create the struct by zeroing out all of the values, without having to call the constructor.

另一方面,结构都是有价值的。它们也没有默认的无参数构造函数,C#不允许您创建一个(尽管CLR会这样做)。由于没有构造函数,CLR能够通过将所有值清零来非常有效地创建结构,而无需调用构造函数。

You can view more about why this is from this * question.

您可以从此*问题中查看有关此原因的详细信息。

#3


2  

When you initialize an array, default values are assigned to its elements:

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

  • null for reference types,
  • null为引用类型,
  • for value types, the default value varies: zero for types representing numbers, for struct it is little bit different, its default value is struct with all fields set to their default values. Again, for reference types it's null and for value types it depends (as mentioned above).
  • 对于值类型,默认值是变化的:对于表示数字的类型为零,对于struct,它有点不同,其默认值为struct,所有字段都设置为其默认值。同样,对于引用类型,它是null,对于它所依赖的值类型(如上所述)。

So, basically, when you initialize array you have your structs initialized (set to default value), that's why you can access their properties.

因此,基本上,当您初始化数组时,您的结构已初始化(设置为默认值),这就是您可以访问其属性的原因。