根据文件:
此方法旨在帮助编译器支持值类型数组;大多数用户不需要这种方法。
此方法如何负责使编译器支持值类型?至于我关心这个方法只是:
通过调用值类型的默认构造函数来初始化value-type Array的每个元素。
另外,为什么公开?我不认为自己需要调用这个方法,编译器在创建时已经初始化了数组,所以手动调用这个方法将是多余的,没用。
即使我的意图是重置数组的值,我仍然不会调用它,我会创建一个新的。 array = new int[]
。
所以,似乎这个方法只是为了编译器而存在。为什么是这样?谁能给我更多细节呢?
答案 0 :(得分:12)
值得注意的是,.NET的规则与C#的规则不同。
我们可以在.NET中做些我们无法在C#中做的事情,通常是因为代码不可验证(例如ref
返回类型),或者因为它们可能引入一些混淆。
在C#struct
中,不能有一个已定义的无参数构造函数,并且调用new SomeValueType()
可以通过创建零填充的内存部分来工作(因此,对于数字类型,所有字段都是0
,{ {1}}用于引用类型,并且对于其他值类型再次使用相同规则的结果。)
在.NET中,您可以在值类型上使用无参数构造函数。
这样做可能是一个坏主意。一方面关于它被调用的规则以及当值的内存被填零时的规则,以及在不同情况下分配时发生的事情都不是完全简单的(例如null
会调用它但是new SomeValueType()
为new T()
的通用方法中的T
不会!)。如果SomeValueType
的结果总是零填充,则生活会更简单。毫无疑问,这会影响C#的设计,即使.NET确实如此。
由于这个原因,Array.Initialize()对于用C#编写的任何类型的新数组都没有意义,因为调用构造函数和零填充是一回事。
但是出于同样的原因,一个类型可以用另一种.NET语言编写(至少,你可以在CIL中编写),它确实有一个实际上有效的无参数构造函数。由于这个原因,这种语言的编译器可能希望它等效于new SomeValueType()
来调用数组中所有类型的构造函数。因此,在框架中使用允许完成此类填充的方法是明智的,这样这种语言的编译器就可以使用它。
另外,为什么要公开?
因此,即使在安全限制阻止它调用另一个程序集的私有方法的上下文中,也可以通过这种假设构造函数生成的代码调用它。
答案 1 :(得分:1)
对我来说,看起来Initialize()方法在数组中运行并重新创建 Value Types 。因此,使用 new array ,您将获得一个新的空数组,因此您可以使用 Array.Clear(),但使用 Array.Initialize()你得到一个完整的值类型的数组(基于旧数组的类型和长度)。
这应该是完全不同的。
答案 2 :(得分:0)
基于CLR source,该方法遍历数组的每个索引,并通过调用默认构造函数初始化该索引上的值类型,类似于initobj
IL指令(我想知道当虽然构造函数抛出异常。该方法是公开的,因为直接从IL调用私有方法会使它有点无法验证。
今天的C#编译器在创建时不会初始化数组的每个元素,只需"设置"每个索引到该类型的默认值。 C#6引入了实现值类型的默认构造函数(CLR已经支持),因此具有不同数组创建语义的语言需要这样做。
答案 3 :(得分:0)
您可以在测试代码中看到预期用途:
基本上,它将非内在值类型的数组设置回其默认(T)状态。
它似乎不是一个非常有用的工具,但我可以看到它如何有效地将非内在价值数据的数组归零。