为什么C#中的ArrayList不安全

本文关键字:不安全 ArrayList 中的 为什么 | 更新日期: 2023-09-27 18:00:06

我最近听说System.CollectionsArrayList不安全,有什么问题?安全是:可能有错误,或者可能有不想要的行为。

为什么C#中的ArrayList不安全

它不是强类型的,也不是固有的线程安全*。有更好的替代方案支持强类型,例如System.Collections.Generic.List<T>

ArrayList不支持编译时类型检查,可能会引入装箱/取消装箱开销,而且通常使用起来更混乱。它是在泛型之前引入的,从而消除了上述问题。

  • 通用列表
  • 线程安全集合

*为了准确起见,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];

现在,如果安全是指线程安全(与类型安全相反),那么这是一件完全不同的事情。ArrayListList<T>都不是线程安全类。这意味着,例如,如果您试图从一个线程读取集合,而另一个线程正在修改它,则可能会得到异常或损坏的数据。在.NET 4.0中,引入了线程安全集合。

这是不安全的,因为以下在运行时失败:

myArrayList.Add(new Banana());
Airplane obj = (Airplane)myArrayList[0];

编译器无法检测到您正试图将Banana用作飞机,因为ArrayList只获取并返回objects,而.NET中的所有内容都是object

自.NET 2.0以来,ArrayList基本上已被System.Collections.Generics.List(T)所取代;它是一个更强类型的替换,不允许出现这种错误。