ArrayList 有什么问题?

20

最近我在 SO 上提出了一个问题,其中提到可能使用 C# 的 ArrayList 来解决。有人评论说使用 ArrayList 是不好的。我想更了解一下此事。我以前从未听说过关于 ArrayList 的这种说法。

C#、.NET-2


2
忽略任何性能问题,自2.0版本以来,我想不出有什么情况下你会更喜欢ArrayList而不是泛型。 - Nick Craver
即使您需要一个对象列表,您也可以使用List<object>。 - recursive
5
泛型是在.NET 2.0中引入的。 - STW
3
@DOK:泛型是在2.0版本中添加的,我不明白你的评论,请解释一下? 回复:泛型是指在编程中使用类型参数来增强程序的灵活性和可重用性。根据@DOK所说,泛型在2.0版本中被引入。但是,我不太理解您的评论,请进一步解释一下。 - Nick Craver
6个回答

37

ArrayList的主要问题是它使用object - 这意味着你必须对你所封装的任何东西进行强制类型转换。这是在泛型出现之前的遗留问题,可能只是为了向后兼容。

与通用列表相比,ArrayList没有类型安全性。性能问题在于需要将对象强制转回原始类型(或发生隐式装箱)。

每当使用值类型时,都会发生隐式装箱 - 当放入ArrayList中时,它将被装箱,当被引用时则会取消装箱。

问题不仅在于性能,还包括可读性和正确性。自从泛型出现以来,这个对象就已经过时了,只有在.NET 1.0/1.1代码中才需要它。


@Russ Cam - 感谢您的评论。在您发表评论时,已更新答案 ;) - Oded

14

如果你要存储值类型(int,float,double等或任何结构体),使用ArrayList会导致每次存储时的装箱和每次访问元素时的拆箱。这可能对性能造成重大影响。

此外,ArrayList完全缺乏类型安全性。由于所有内容都被存储为"object",因此作为开发人员,你需要承担额外的责任来保证其安全。

此外,如果你希望存储对象的行为,你可以始终使用List<object>。 这与ArrayList相比没有任何不利之处,并且它具有一个很大的(在我看来)优点:从一开始就清楚地表明了你的意图(存储未经类型定义的对象)。

ArrayList实际上只存在于.NET 1.1代码中,并且应该仅用于那里。 在.NET 2+中真的没有使用它的理由。


4

ArrayList不是泛型类型,因此必须将放入其中的所有项都存储为对象。这有两个问题。首先,在将值类型放入ArrayList时,您会强制编译器将值类型装箱为引用类型,这可能很昂贵。其次,现在您必须对从数组列表中取出的每个对象进行强制转换。这很糟糕,因为现在您需要确保知道其中有哪些对象。

List避免了这些问题,因为它是使用正确的类型构建的。 例如:

List<int> ints =  new List<int>();
ints.Add(5); //no boxing
int num = ints[0]; // no casting

3

通常使用泛型List<T>,因为它是泛型的,提供了额外的类型信息,并且不需要对添加到其中的值类型进行装箱/拆箱。


@DOK - List<T> 存在于 .net 2.0 中。 - Lee
有没有任何通用等效于vb.net Collection类型的东西,它允许迭代器删除当前项(假设该项的内容包含标识键的信息)?字典可能是一个很好的匹配,除了最后一点。 - supercat

2

除了性能问题之外,这也是将错误从运行时移到编译时的问题。从 ArrayList 检索出来的对象转换必须在运行时发生,而任何类型错误都会在执行期间发现。使用泛型 List<>,所有类型都在编译时进行检查。


使用List<int>而不是包含int的ArrayList可以大幅提高性能。 - tster
这不是一个关于性能的问题。然而,性能问题是答案的一部分。 - AMissico
从OP的话来看:“有人能让我了解使用ArrayList可能存在的性能问题吗?” - tster
@tster:我看到了相关的帖子,主要反对意见似乎并不是与性能有关。尽管如此,我已经更改了措辞。 - recursive
也许“性能”并不是一个正确的术语,因为英语不是我的母语,我并不总是将“性能”这个词与速度相关的维度联系起来。 - fishhead

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接