我最近听说来自ArrayList
的{{1}}不安全,问题是什么?
安全是:可能有错误,或者可能有不良行为。
答案 0 :(得分:9)
它不是强类型,也不是固有的线程安全*。有更好的替代方案支持强类型,例如System.Collections.Generic.List<T>
。
ArrayList
不支持编译时类型检查,可能会引入装箱/拆箱开销,一般来说使用起来比较麻烦。它是在仿制药之前引入的,它消除了上述问题。
*为了准确起见,ArrayList确实公开了一个Synchronized
属性,它提供了一定程度的线程安全性(see notes at end of article)。
答案 1 :(得分:8)
它们不安全,因为它们没有强类型。这意味着您在编译时不知道可以存储在其中的对象类型。此外,您还需要转换为实际类型,这意味着您只能在运行时获取错误。您应该使用泛型和强类型等效List<T>
。
看一下下面的例子,你需要将从ArrayList获得的结果转换为实际类型:
ArrayList list = new ArrayList();
list.Add(123);
int element = (int)list[0];
如果你使用了错误的类型,那么事情就会变得严重错误,你的程序只会在运行时崩溃。
然而使用List<T>
你不需要这个演员,你可以获得编译时的安全性:
List<int> list = new List<int>();
list.Add(123);
int element = list[0];
现在,如果 safety 意味着线程安全(与类型安全相反),那么这是完全不同的事情。 ArrayList
和List<T>
都不是线程安全的类。这意味着,例如,如果您尝试从一个线程读取集合而另一个线程正在修改它,则可能会收到异常或损坏的数据。在.NET 4.0中,引入了thread safe collections。
答案 2 :(得分:2)
这是不安全的,因为以下在运行时失败:
myArrayList.Add(new Banana());
Airplane obj = (Airplane)myArrayList[0];
编译器无法检测到您正在尝试将Banana用作飞机,因为ArrayList仅返回object
,并且.NET中的所有内容都是object
。
ArrayList
基本上被System.Collections.Generics.List(T)
取代;它是一种更强类型的替代品,不允许出现这种错误。