在讨论关于 SO 的另一个问题时,有人告诉我语法
int[] numbers = new int[10];
优于
Array numbers = Array.CreateInstance(typeof(int), 10);
我的问题是,第一种语法什么时候有用,第二种语法什么时候有用?为什么?
这会“直接”创建一个强类型的单维数组:
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
'/ something
)。所以:
int num = (int)array2.GetValue(1); // You have to cast the return value to int from object
另一个使用理由
array[5] = 1;
代替
array2.SetValue(5, 1);
是第一种方法在 IL 代码中被优化为直接访问一维数组 (stelem
和ldelem
)。对于GetValue
.
我使用术语“一维数组”的原因:
在 .NET 中有两种“类型”的数组:单维数组和“复杂”数组(它们可以是多维的,或者第一个元素不在 0 索引处,或两者兼而有之)。第二组要慢得多。和stelem
仅ldelem
适用于一维数组。对于多维/特殊数组,“隐藏”方法用于访问它们(C# 编译器更改 get 和 set 以便调用这些方法)(它们类似于类的GetValue
/ SetValue
,Array
例如参见https://stackoverflow。 com/a/597729/613130)
在编译时,看起来它们之间没有太大区别。就像数组一样,Array.CreateInstance方法也使引用类型的元素初始化为null
. 值类型元素被初始化为zero
.
第二个的唯一区别是;来自MSDN;
与大多数类不同,Array 提供了 CreateInstance 方法,而不是公共构造函数,以允许后期绑定访问。
同样正如 Stefano Altieri 所提到的,第一种语法在编译时需要数组大小,但第二种语法需要在运行时的大小。例如,您可以成功构建这些代码;
int[] numbers1 = new int[10];
Array numbers2 = Array.CreateInstance(typeof(int), -1);
但是你不能建造这些;
int[] numbers1 = new int[];
Array numbers2 = Array.CreateInstance(typeof(int), -1);
您编写的示例是等效的。关键是要使用第一种语法(new int[size]),您需要在编译时知道数组类型。
第二种语法允许您在运行时决定数组项的类型。这要强大得多,但您并不总是需要这种力量。IE
Type myType = SelectTheBestType();
var numbers = Array.CreateInstance(myType, 10);
Soner Gönül的回答非常好。你的问题的一个简单原因是
如果数组作为对象或接口传递,则元素类型在编译时是未知的。
[这个答案]可能会给你带来这个想法,[这里]是一些代码示例。
第一种语法什么时候有用,第二种语法什么时候有用?
示例链接中的方法,
static IList CreateArray<T>(this T source);
泛型类型参数T
不是T[]
因为我不能假设它source
一定是一个数组,但它仍然可能。因此我只能Array.CreateInstance
在方法内部使用。
大多数时候,如果元素类型在编译时已经知道,最好使用语言提供的语法。