[英]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代码中被优化为直接访问单维数组(
stelem
和ldelem
)。 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. stelem
和ldelem
仅适用于单维数组。 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.