ArrayList与对象数组相对于Collection of T

时间:2009-02-21 20:03:41

标签: c# arrays generics collections

我有一个类Customer(具有典型的客户属性),我需要传递和数据绑定Customer个实例的“块”。目前我正在使用Customer数组,但在我了解{Collection之前,我还使用了T List T Collection 1 {} T)。我想用最简洁的方法来使用C#和.NET 3.5来传递这个块。

目前,Customer的数组对我来说效果很好。它的数据绑定得很好,似乎也很轻巧。我不需要List提供的T内容,而Collection的{​​{1}}仍然看起来有点矫枉过正。该阵列确实要求我提前知道我正在向块中添加多少T,但我总是事先知道(例如,在页面中给定行)。

我错过了一些基本的东西,还是Customer的数组?我缺少一个权衡吗?

另外,我假设Customer Collection使旧的松散类型T过时了。我在那儿吗?

6 个答案:

答案 0 :(得分:11)

是的,Collection<T>(或更常见的List<T>)使ArrayList过时了。特别是,我相信在Silverlight 2中甚至不支持ArrayList

在某些情况下阵列是可以的,但应该是considered somewhat harmful - 它们有各种缺点。 (当然,它们是大多数集合的实现的核心......)我会详细介绍,但Eric Lippert在文章中做得比我在文章中做得更好由链接引用。我会在这里总结一下,但这很难做到。真的值得读完整篇文章。

答案 1 :(得分:4)

没有人提及框架指南建议:Don't use List<T> in public API's

  

我们不建议使用List   公共API有两个原因。

     
      
  • List<T>并非旨在扩展。即你不能覆盖任何   成员。这例如意味着   从a返回List<T>的对象   财产将无法得到通知   当集合被修改。   Collection<T>可让您覆盖   获取的SetItem受保护成员   添加新项目时“通知”   或现有项目已更改。

  •   
  • 列表中有许多成员在许多情况下都不相关。我们   说List<T>太“忙”了   公共对象模型。想像   ListView.Items属性返回   List<T>充满了它的丰富性。现在,   看看实际ListView.Items   返回类型;它更简单   类似于Collection<T>或   ReadOnlyCollection<T>

  •   

此外,如果您的目标是双向数据绑定,请查看BindingList<T>(但需要注意的是,它不能开箱即用!)

答案 2 :(得分:3)

通常,你应该“传递”IEnumerable&lt; T&gt;或ICollection&lt; T&gt; (取决于您的消费者添加商品是否有意义。)

答案 3 :(得分:1)

如果您有一个不可变的客户列表,那就是......您的客户列表不会改变,它相对较小,您将始终首先迭代它并且您不需要添加到列表中或从中删除,然后一个数组可能就好了。

但是,如果您不确定,那么您最好的选择是某种类型的集合。您选择的集合取决于您希望在其上执行的操作。集合都是关于插入,操作,查找和删除。如果频繁搜索给定元素,那么字典可能是最好的。如果您需要对数据进行排序,那么SortedList可能会更好。

我不担心“轻量级”,除非你说的是大量的元素,即使这样,O(1)查找的优势也超过了资源的成本。

当你“传递”一个集合时,你只传递一个引用,它基本上是一个指针。因此,传递集合和数组之间没有性能差异。

答案 4 :(得分:0)

我要向Jon和Eric Lippert提出不同意见,这意味着你应该非常厌倦我的答案,确实!)。

Eric Lippert反对数组的论点的核心是内容是不可变的,而数据结构本身则不是。关于从方法返回它们,List的内容也是可变的。实际上,因为你可以在List中添加或减去元素,我认为这会使返回值 more 比数组更可变。

我喜欢Arrays的另一个原因是因为有时候我只有一小部分性能关键代码,所以我对两者的性能特征进行了基准测试,并且数组将列表吹出了水面。现在,请允许我指出这是对我在特定情况下如何使用它们的狭隘测试,这与我对两者的理解相违背,但数字却截然不同。

无论如何,听Jon和Eric =),我同意List几乎总是更有意义。

答案 5 :(得分:0)

我赞同Alun,还有一个补充。如果你想通过下标myArray [n]来解决返回值,那么使用IList。

Array固有地支持IList(以及IEnumerable和ICollection)。因此,如果您通过接口传递,您仍然可以使用该数组作为基础数据结构。通过这种方式,您传递数组的方法不必“知道”底层数据结构是一个数组:

        public void Test()
{
    IList<Item> test = MyMethod();
}

public IList<Item> MyMethod()
{
    Item[] items = new Item[] {new Item()};
    return items;
}