C#在这方面与JavaScript有些不同。由于严格的检查,您定义数组的大小,并且应该了解有关数组的所有内容,例如其边界、最后一个项目的位置以及未使用的项目。如果要调整大小,则应将数组的所有元素复制到新的、更大的数组中。
因此,如果您使用原始数组,则除了维护最后一个空的可用index
并在此索引处分配项目之外,没有其他方法,就像您已经做的那样。
但是,如果您想让运行时维护此信息并完全抽象化数组,但仍然在底层使用数组,则C#提供了一个名为ArrayList
的类,提供此抽象。
ArrayList
抽象了一个松散类型的Object
数组。请参见此处的源代码。
它处理所有问题,如调整数组大小、维护最后可用的索引等。但是,它将此信息抽象/封装起来,使您只使用ArrayList
。
要将任何类型的项推送到底层数组的末尾,请调用ArrayList
上的Add
方法,如下所示:
var arrayList = new ArrayList();
arrayList.Add("Foo");
编辑:关于类型限制的说明
与所有编程语言和运行时一样,C#将堆对象分类为不会进入堆的仅保留在函数参数堆栈上的对象。 C#通过名称值类型 vs. 引用类型来区分这个差异。所有值进入堆栈的事物都称为值类型,而进入堆的则称为引用类型。这与JavaScript的对象和字面量之间的区别类似,但并不完全相同。
在C#中,您可以将任何内容放入ArrayList
中,无论该内容是值类型还是引用类型。就类型缺失而言,这使它与JavaScript数组最接近,尽管三者中没有一个(JavaScript数组,JavaScript语言和C#ArrayList)是真正的无类型。
因此,您可以将数字文字,字符串文字,您自己创建的类的对象,布尔值,浮点数,双精度数,结构等任何东西放入ArrayList
中。
这是因为ArrayList
在内部维护并存储您放入其中的所有内容,将其存储为Object
数组,正如您在我的原始答案和链接源代码中所注意到的那样。
当您放入的内容不是对象时,C#会创建一个新的Object
类型的对象,将您放入ArrayList
中的东西的值存储在这个新的Object
类型的对象中。此过程称为装箱,与JavaScript的装箱机制非常相似。
例如,在JavaScript中,虽然您可以使用数字字面量调用Number
对象上的函数,但无法向数字字面量的原型添加任何内容。
// Valid javascript
var s = 4.toString();
// Invalid JavaScript code
4.prototype.square = () => 4 * 4;
var square = 4.square();
就像JavaScript在调用toString方法时将数字文字4装箱一样,当将非对象类型放入ArrayList中时,C#会将所有不是对象的东西都装箱为Object类型。
var arrayList = new ArrayList();
arrayList.Add(4);
这涉及到一定的惩罚,就像在JavaScript中一样。
在C#中,您可以避免这种惩罚,因为C#提供了一个强类型版本的ArrayList
,称为List<T>
。因此,您不能将任何东西放入List<T>
; 只有T
类型。
然而,我从您的问题文本中假设您已经知道C#具有用于强类型项的通用结构。您的问题是要求类似于JavaScript的数据结构,展现出无类型和弹性的语义,比如JavaScript的Array
对象。在这种情况下,ArrayList
最接近。
从您的问题中也清楚地看出,您的兴趣是学术性的,而不是在生产应用程序中使用这个结构。
因此,我假设对于生产应用程序,您已经知道泛型/强类型数据结构(例如List<T>
)比其非类型化数据结构(例如ArrayList
)具有更好的性能。
push
方法并允许添加项目?你能发一份证明吗?我不是Java专家,试图搜索push
文档以帮助您找到C#等效项,但我发现Java中的数组与C#中的行为相同。您是指JS而不是Java吗? - Dennis