我最近听说ArrayList
fromSystem.Collections
不安全,是什么问题?安全是:可能有错误,或者可能有不想要的行为。
3 回答
它不是强类型的,也不是固有的线程安全*。有更好的替代方案支持强类型,例如System.Collections.Generic.List<T>
.
AnArrayList
不支持编译时类型检查,可能会引入装箱/拆箱开销,并且通常使用起来更加混乱。它是在泛型之前引入的,从而消除了上述问题。
*为了准确起见,ArrayList 确实公开了一个Synchronized
提供线程安全级别的属性(请参阅文章末尾的注释)。
它们不安全,因为它们不是强类型的。这意味着您在编译时不知道可以存储在其中的对象的类型。此外,您需要转换为实际类型,这意味着您只会在运行时收到错误。您应该改用通用的强类型等效项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];
现在,如果安全是指线程安全(与类型安全相反),那么这是完全不同的事情。两者都不是线程安全的类ArrayList
。List<T>
这意味着,例如,如果您尝试从一个线程读取集合,而另一个线程正在修改它,您可能会收到异常或损坏的数据。在 .NET 4.0 中,引入了线程安全集合。
这是不安全的,因为以下在运行时失败:
myArrayList.Add(new Banana());
Airplane obj = (Airplane)myArrayList[0];
编译器无法检测到您正在尝试将 Banana 用作 Airplane,因为 ArrayList 只接受并返回object
s,而 .NET 中的所有内容都是object
.
ArrayList
System.Collections.Generics.List(T)
自 .NET 2.0 以来,基本上已被替换;它是一种更强类型的替换,不允许出现这种错误。