为啥 ArrayList 没有标记为 [过时]?

Posted

技术标签:

【中文标题】为啥 ArrayList 没有标记为 [过时]?【英文标题】:Why isn't ArrayList marked [Obsolete]?为什么 ArrayList 没有标记为 [过时]? 【发布时间】:2011-07-01 02:15:03 【问题描述】:

经过深思熟虑,研究了ArrayList的实现,我个人很想说已经过时了,2.0以后我没有理由使用这个类。但是由于它没有标记为[Obsolete],所以有什么我不知道的用法,比使用泛型类更好吗?如果是,请举个例子。谢谢。

EDIT 我们以List<T> 为例,它提供了ArrayList 的所有功能,并且是强类型的。那么我们什么时候需要使用ArrayList呢?也许有时它有更好的表现?我不知道。如果你能告诉我ArrayList 的特别之处,我将不胜感激。

【问题讨论】:

@glowcoder:将其与泛型进行比较。 我认为您已经决定泛型已经使其在功能上过时了。所以这个问题真的是“为什么.NET 团队还没有用[Obsolete] 属性标记它?”能够回答那个问题的人非常有限。 马上,List 不像 ArrayList 那样实现 ICloneable。 @Cody Gray:我只是想确保泛型总是优于 ArrayList,以防万一我不知道...... @xanatos:又是一个圆圈。如果我不再使用 ArrayList,为什么我需要将 IList 转换为 ArrayList? 【参考方案1】:

它本身并不是“过时的”。作为'70 '80 90 年代早期的汽车,它已经“过时”了。如果我必须在 List<Object>ArrayList 之间进行选择,我会使用 ArrayList 的可能性非常小……算了吧……它没有实现 IEnumerable<Object>,所以要使用 Linq,我会必须使用OfType<Object>()

举个例子:

var aaa = new ArrayList();
var aaaa = aaa.OfType<object>().Where(p => p != null);

var bbb = new List<object>;
var bbbb = bbb.Where(p => p != null);

终于有人对我的回复投了赞成票,所以我会添加一些内容:-)

如果您问“您会使用任何非通用集合”,我的回答会有所不同。 Hashtable 有一个有趣的属性:

Hashtable 是线程安全的,可供多个读取线程和单个写入线程使用。当只有一个线程执行写入(更新)操作时,多线程使用是线程安全的,如果写入器序列化到哈希表,则允许无锁读取。

所以有些地方Hashtable 应该比lock + DictionaryConcurrentDictionary 更好(但你必须对其进行基准测试)

【讨论】:

您的答案看起来像一个圆圈。你想表达什么观点?是不是已经过时了? 作为 70 年代的汽车。如果你可以在 70 年的汽车和 2010 年的汽车之间以相同的价格选择,你会买什么?我很讽刺(“忘记它”部分) @xanatos:古董收藏家会选择 70 年代的汽车。 @Danny - 也许一个古董代码的收集者会收集 COBOL 和 ArrayLists。 @Danny 所以你可以使用你的 .NET 1.1 并快乐地生活 :-) '70 辆汽车仍然是合法的,但 90% 的人会购买 2010 年的汽车,通常 更好。你看,我的比喻比我想象的要好 :-) :-)【参考方案2】:

实际上它已完全从 Silverlight 中删除 - 所以意图就在那里。据推测,regular .NET 的现有代码太多了,它们使用 ArrayList 来淘汰它,尤其是因为很多人在运行时都会遇到警告作为错误。

你不应该在没有充分理由的情况下在新代码中使用它。

【讨论】:

+1 表示“警告为错误”。 Eric Lippert 多次提到他们确实为使用该开关的用户制定了计划【参考方案3】:

我认为它应该被认为对于新代码实际上已经过时,但没有令人信服的理由将其标记为过时并在所有在 2.0 发布之前编写的代码中创建警告。

根据我的经验,大多数已被 Microsoft 标记为过时的类型和成员在某些方面都非常危险,如果您仍然有使用它们的代码库,应该真正修复它们。虽然使用ArrayList 很痛苦并且(至少在理论上)容易在执行时而不是编译时发现与类型相关的错误,但该类型的工作已经足够好......通常确实没有令人信服的理由来更改现有代码。当我碰巧正在处理使用 ArrayList 的代码区域时,我通常会考虑这种更改,而不是积极寻找它的每一种用法。

【讨论】:

+1 因为这是一个非常好的回应。一些示例是 Thread.Suspend、Thread.Resume。 我希望 .net 编译器有一个“遗留框架元素警告”标志。 IE。如果今天从头开始重新创建框架 4 和相关语言,这些元素将会消失。 不是每个人都可以抛出 Python :-)(对 Python 3.0 的引用,它“清理了混乱”并且与 Python 2.0 部分不兼容)......或者......不是每个人都可以重新抛出一个 VB.NET(对与 VB 6.0 不兼容的 VB.NET 的引用) @vc 74:像 [Obsolete, from=4.0] 这样的东西会很棒。如果项目的目标是 2.0,一切都很好,如果目标是 4.0,则会给出警告。 @Mene:是的,我也会很高兴有一个更严格的选项,比如 [EnforceBackwardCompatibility=false]。这可能是 MS 可以发布的一组 fxcop 规则。

以上是关于为啥 ArrayList 没有标记为 [过时]?的主要内容,如果未能解决你的问题,请参考以下文章

如何在注销功能中将会话 ID 标记为已过时 [重复]

为啥 Arrays.asList() 返回自己的 ArrayList 实现

为啥我没有从 ArrayList 获取 ListView 数据?

为啥 ArrayList 没有实现 Queue?

为啥 System.ServiceModel.Persistence 过时了?

为啥我的 ArrayList 没有打印出 Java 所需的输出?