简体   繁体   English

声明一个数组类型

[英]Declaring an array type

While discussing another question on SO, I was told that the syntax 在讨论关于SO的另一个问题时,我被告知语法

int[] numbers = new int[10];

Is better than 比。更好

Array numbers = Array.CreateInstance(typeof(int), 10);

My question is, when is the first syntax useful and when is the second syntax useful? 我的问题是,第一个语法何时有用,何时第二个语法有用? And why? 为什么?

This creates a strongly typed monodimensional array "directly": 这会“直接”创建一个强类型的单维数组:

int[] array = new int[10];

Under the hood it uses the IL command newarr . 在引擎盖下它使用IL命令newarr

This one is more similar to using reflection to create an array (the type can be decided at runtime) 这个更像是使用反射来创建一个数组(类型可以在运行时决定)

int[] array2 = (int[])Array.CreateInstance(typeof(int), 10);

The array created in the end is the same but the speed of creating it is much slower when using Array.CreateInstance . 最后创建的数组是相同的,但使用Array.CreateInstance时创建它的速度要慢Array.CreateInstance Note that with Array.CreateInstance you can dynamically select the type of the array (in the same way that through reflection you can create an instance of a type given the type at runtime), for example: 请注意,使用Array.CreateInstance您可以动态选择数组的类型(与通过反射相同的方式,您可以创建在运行时给定类型的类型的实例),例如:

Type type = someCondition ? typeof(int) : typeof(string);
Array array2 = Array.CreateInstance(type, 10);

Another big difference: the "base" Array class is weakly typed (so its methods use object parameters, instead of int / string '/ something ). 另一个很大的区别是:“base” Array类是弱类型的(因此它的方法使用object参数,而不是int / string '/ something )。 So: 所以:

int num = (int)array2.GetValue(1); // You have to cast the return value to int from object

Another reason to use 使用的另一个原因

array[5] = 1;

instead of 代替

array2.SetValue(5, 1);

is that the first method is optimized in the IL code as a direct access to a monodimensional array ( stelem and ldelem ). 是第一种方法在IL代码中被优化为直接访问单维数组( stelemldelem )。 The same is true for GetValue . GetValue也是如此。


The reason I'm using the term "monodimensional array": 我使用术语“单维数组”的原因:

In .NET there are two "types" of arrays: the monodimensional arrays and the "complex" arrays (they can be multidimensional, or with the first element not at the 0 index, or both). 在.NET中,有两种“类型”的数组:单维数组和“复杂”数组(它们可以是多维的,或者第一个元素不在0索引处,或两者都有)。 The second group is much slower. 第二组要慢得多。 The stelem and ldelem work only with monodimensional arrays. stelemldelem仅适用于单维数组。 For multidimensional/special arrays "hidden" methods are used to access them (the C# compiler changes the get and set so that these methods are called) (they are similar to the GetValue / SetValue of the Array class, see for example https://stackoverflow.com/a/597729/613130 ) 对于多维/特殊数组,“隐藏”方法用于访问它们(C#编译器更改get和set以便调用这些方法)(它们类似于Array类的GetValue / SetValue ,请参阅https:/ /stackoverflow.com/a/597729/613130

On compile time, looks like there is no big difference between them. 在编译时,看起来它们之间没有太大的区别。 Just like arrays, Array.CreateInstance method also make reference-type elements are initialized to null . 就像数组一样, Array.CreateInstance方法也使得reference-type元素被初始化为null value-type elements are initialized to zero . value-type元素初始化zero

在此输入图像描述

Only difference for the second one is; 只有第二个的区别是; from MSDN ; 来自MSDN ;

Unlike most classes, Array provides the CreateInstance method, instead of public constructors, to allow for late bound access. 与大多数类不同,Array提供CreateInstance方法而不是公共构造函数,以允许后期绑定访问。

Also as Stefano Altieri mentioned , first syntax requires array size in compile time , but the second one need the size in run-time . 另外,正如Stefano Altieri所提到的 ,第一种语法需要在编译时使用数组大小,但第二种语法需要运行时的大小。 For example, you can build these codes successfully; 例如,您可以成功构建这些代码;

int[] numbers1 = new int[10];
Array numbers2 = Array.CreateInstance(typeof(int), -1);

But you can't build these; 但你无法建立这些;

int[] numbers1 = new int[];
Array numbers2 = Array.CreateInstance(typeof(int), -1);

The samples you wrote are equivalent. 你写的样本是等价的。 The point is that to use the first syntax (new int[size]) you need to know the array type at compile time. 关键是要使用第一种语法(new int [size]),您需要在编译时知道数组类型。

The second syntax allow you to decide at runtime the type of the array items. 第二种语法允许您在运行时决定数组项的类型。 This is far more powerful, but you just don't need this power always. 这更强大,但你总是不需要这种力量。 Ie

Type myType = SelectTheBestType();
var numbers = Array.CreateInstance(myType, 10);

Soner Gönül 's answer is pretty good. SonerGönül的回答非常好。 A simple reason of your question is 你问题的一个简单原因是

If an array is passed as object or interface, the element type is unknown at compile time. 如果数组作为对象或接口传递,则元素类型在编译时是未知的。

[ This answer ] might bring you the idea, and [ here ] is some code for example. [ 这个答案 ]可能会给你带来这个想法,[ 这里 ]是一些代码。

when is the first syntax useful and when is the second syntax useful? 何时第一种语法有用,何时第二种语法有用?

The method in the link of example, 链接示例中的方法,

static IList CreateArray<T>(this T source);

the generic type parameter is T rather than T[] because of I cannot suppose that source necessarily been an array, but it still possibly . 泛型类型参数是T而不是T[]因为我不能假设source 必然是一个数组,但它仍然可能 Thus I can only use Array.CreateInstance inside the method. 因此我只能在方法中使用Array.CreateInstance

Most of time, if the element type is already known at compile time, it's better to use the syntax provided by the language. 大多数情况下,如果在编译时已知元素类型,则最好使用该语言提供的语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM