为什么ArrayList没有被标记为[已过时]?

39

经过深思熟虑并查看了 ArrayList 的实现后,我个人真的想说它已经过时了,2.0版本之后我没有理由使用这个类。但是既然它没有被标记为 [Obsolete],是否有一些我不知道的用法比使用通用类更好?如果有,请举例说明。谢谢。

编辑List<T> 为例,它提供了 ArrayList 的所有功能,并且它是强类型的。那么我们什么时候需要使用 ArrayList 呢?也许有时它的性能更好吗?我不知道。如果您能给我展示一些 ArrayList 的特殊之处,我将不胜感激。


1
与泛型进行比较。 - Cheng Chen
2
我认为你已经决定了泛型已经使其在功能上过时了。所以这个问题实际上是“为什么.NET团队还没有用[Obsolete]属性标记它?”能够回答那个问题的人非常有限。 - Cody Gray
2
一开始,List<T> 没有像 ArrayList 一样实现 ICloneable 接口。 - corsiKa
2
@Cody Gray:我只是想确保在我不知道的情况下,泛型始终比ArrayList更好... - Cheng Chen
2
@xanatos:又是一个循环。如果我不再使用ArrayList,为什么需要将IList转换为ArrayList? - Cheng Chen
显示剩余7条评论
3个回答

49

我认为它应该被视为新代码中无效的,但没有强制性的理由来标记它为过时并在2.0发布之前编写的所有代码中创建警告。

根据我的经验,微软标记为过时的大多数类型和成员在某些方面是活动风险,如果你仍然有一个使用它们的代码库,真的应该进行修复。虽然使用ArrayList很痛苦(至少在理论上)容易在执行时发现与类型相关的错误而不是编译时,但这个类型足够好地完成了工作......通常没有强制性的理由来更改现有的代码。通常只有当我已经在使用ArrayList的代码区域工作时才会考虑这种更改,而不是积极寻找每一种用法。


+1 因为这是非常好的回答。一些示例是 Thread.Suspend,Thread.Resume。 - xanatos
7
我希望.NET编译器能够添加一个“警告过时框架元素”的标志。即那些如果从头开始重新创建框架4及其相关语言就会消失的元素。 - vc 74
不是每个人都能够掷出 Python :-)(这是对 Python 3.0 的引用,它“清理了混乱”,并且与 Python 2.0 部分不兼容)... 或者... 不是每个人都能够重新抛出 VB.NET(这是对 VB.NET 的引用,它与 VB 6.0 不兼容)。 - xanatos
1
@vc 74:类似 [Obsolete, from=4.0] 这样的东西会很好。如果项目目标是2.0,那么一切都没问题,但如果目标是4.0,则会产生警告。 - Mene
2
@Mene:是的,我也很乐意使用更严格的选项,比如[EnforceBackwardCompatibility=false]。这可以是一组由微软提供的FxCop规则。 - vc 74

15

实际上,它已完全从Silverlight中移除 - 因此意图是明确的。大概是因为有太多使用ArrayList的旧的现有代码,以至于使它过时在正常的.NET中,尤其是因为很多人运行时开启了警告视为错误。

没有充分的理由,您不应在新代码中使用它。


“警告视为错误”加1分。Eric Lippert多次提到他们计划为使用该开关的用户提供支持。 - Michael Stum
“计划适用于使用该开关的用户” - 这应该是所有用户。事实上,不应该有这样的开关,它应该是默认行为和唯一行为。没有人应该使用生成警告的构建产生的二进制文件。 - Mike Nakis
错误和警告之间的区别被广泛理解为,如果出现错误,您必须在继续之前修复它,而如果出现警告,则可以忽略它并继续。这是错误的。区别应该是您可以抑制警告,而无法抑制错误。但是,所有新手程序员都应该被迫处理所有警告,通过解决它们或有意识地明确抑制它们,然后才允许继续进行。 - Mike Nakis

5

它本身并不是“过时的”。它在70年代、80年代早期已经“过时”了。如果我必须在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 中进行无锁读取,前提是编写者序列化到 Hashtable。

因此,在某些情况下,Hashtable 应该比 lock + DictionaryConcurrentDictionary 更好(但您需要对其进行基准测试)。


9
你的回答读起来像个圆圈。你想表达什么观点?它是否过时了? - Cody Gray
1
作为一辆70年代的汽车,如果你可以在同样的价格下选择一辆70年代的汽车和一辆2010年的汽车,你会选择哪一个?我是在讽刺("算了吧"这部分)。 - xanatos
5
一个古董收藏家会选择一辆70年代的车。 - Cheng Chen
4
也许一个古董代码收藏家会收集COBOL和ArrayLists。 - Greg
1
@Danny,所以你可以使用你的.NET 1.1并且过得很开心 :-) '70年代的汽车仍然是合法上路的,但90%的人会购买2010年的汽车,通常情况下更好。你看,我的比喻比我想象中的还要好 :-) :-) - xanatos
显示剩余7条评论

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