在讨论关于SO的另一个问题时,我被告知语法
int[] numbers = new int[10];
优于
Array numbers = Array.CreateInstance(typeof(int), 10);
我的问题是,第一种语法何时有用,何时第二种语法有用?为什么?
答案 0 :(得分:6)
这会“直接”创建一个强类型的单维数组:
int[] array = new int[10];
在幕后,它使用IL命令newarr
。
这个更类似于使用反射来创建数组(类型可以在运行时决定)
int[] array2 = (int[])Array.CreateInstance(typeof(int), 10);
最终创建的数组是相同的,但使用Array.CreateInstance
时创建它的速度要慢得多。请注意,使用Array.CreateInstance
,您可以动态选择数组的类型(与通过反射相同的方式,您可以创建在运行时给定类型的类型的实例),例如:
Type type = someCondition ? typeof(int) : typeof(string);
Array array2 = Array.CreateInstance(type, 10);
另一个重大区别:“基础”Array
类是弱类型的(因此其方法使用object
参数,而不是int
/ string
'/ {{1 }})。所以:
something
使用
的另一个原因int num = (int)array2.GetValue(1); // You have to cast the return value to int from object
而不是
array[5] = 1;
是第一种方法在IL代码中被优化为对一维数组(array2.SetValue(5, 1);
和stelem
)的直接访问。 ldelem
也是如此。
我使用术语“单维数组”的原因是:
在.NET中有两种“类型”的数组:单维数组和“复杂”数组(它们可以是多维的,或者第一个元素不在0索引处,或两者都有)。第二组要慢得多。 GetValue
和stelem
仅适用于单维数组。对于多维/特殊数组,使用“隐藏”方法来访问它们(C#编译器更改get和set以便调用这些方法)(它们类似于ldelem
/ GetValue
{ {1}}类,例如参见https://stackoverflow.com/a/597729/613130)
答案 1 :(得分:5)
在编译时,看起来它们之间没有太大的区别。与数组一样, Array.CreateInstance 方法也会将引用类型元素初始化为null
。 value-type元素初始化为zero
。
唯一不同的是第二个;来自 MSDN ;
与大多数类不同,Array提供CreateInstance方法 公共构造函数,允许后期绑定访问。
另外,作为Stefano Altieri mentioned,第一种语法需要编译时中的数组大小,但第二种语法需要运行时中的大小。例如,您可以成功构建这些代码;
int[] numbers1 = new int[10];
Array numbers2 = Array.CreateInstance(typeof(int), -1);
但你无法建立这些;
int[] numbers1 = new int[];
Array numbers2 = Array.CreateInstance(typeof(int), -1);
答案 2 :(得分:4)
您编写的样本是等效的。关键是要使用第一种语法(new int [size]),你需要在编译时知道数组类型。
第二种语法允许您在运行时决定数组项的类型。这更强大,但你总是不需要这种力量。即
Type myType = SelectTheBestType();
var numbers = Array.CreateInstance(myType, 10);
答案 3 :(得分:2)
Soner Gönül的答案非常好。问题的一个简单原因是
如果数组作为对象或接口传递,则元素类型在编译时是未知的。
[This answer]可能会为您提供这个想法,[here]就是一些代码。
第一个语法何时有用,何时第二个语法有用?
示例链接中的方法
static IList CreateArray<T>(this T source);
泛型类型参数是T
而不是T[]
因为我不能认为source
必然是一个数组,但它仍然可能即可。因此,我只能在方法中使用Array.CreateInstance
。
大多数情况下,如果在编译时已知元素类型,则最好使用该语言提供的语法。