English 中文(简体)
何时在C#中使用ArrayList而不是array []?
原标题:
  • 时间:2009-01-05 11:07:28
  •  标签:

我经常使用 ArrayList 而不是普通的 array[]

当我使用ArrayList时,我感觉好像在作弊(或懒惰),什么时候使用ArrayList比数组更好?

最佳回答

数组是强类型的,并且作为参数很有用。如果您知道您的集合的长度并且它是固定的,则应使用数组。

ArrayList不是强类型的,每次插入或检索都需要强制转换回你的原始类型。如果你需要一个方法来接受特定类型的列表,ArrayList就显得不够用了,因为你可以传递包含任何类型的ArrayList。ArrayList在内部使用动态扩展的数组,因此当它达到容量上限时,扩展内部数组的大小也会对性能产生影响。

你真正想要使用的是像List<T>一样的通用列表。这具有数组和ArrayLists的所有优点。它是强类型的,并支持可变长度的项目。

问题回答

除了Bob和Frederick的回应外,我想指出,虽然数组具有协变性,但泛型列表却没有。例如,类型为MyChildClass[]的数组可以轻松地转换为MyParentClass[],而List<MyChildClass>无法直接转换为List<MyParentClass>

如果需要协方差,可以使用数组,使用LINQ的Cast()方法或其他方法来单独转换每个项,或者等待C# 4版。

这里还有一个想法是变异;数组(T[])是完全可变的,并且无法保护。 List<T> 不提供任何有用的扩展点,但诸如 Collection<T>(或许多其他 IList<T> 实现)之类的东西允许您添加代码,例如在添加它们之前检查项目;同样,您可以有 readonly IList<T> 实现,这对于希望保持不变性的线程安全性非常有用。

我倾向于在内部方法逻辑(可能作为局部变量),作为params参数或在一些高度优化的情况下使用数组,我知道项的长度,并且知道代码选择不要改变它(作为私有字段)。除此之外,List<T>等通常更常见,因为它们在添加/删除项时具有更少的开销。

除非代码中的那部分绝对需要优化性能,否则使用ArrayList是完全可以的。

更好的做法是,在任何使用ArrayList的地方,都应该使用List<T>泛型集合,因为它比前者更强类型化。

我从Java的角度来回答这个问题,但基本问题是一样的。你不应该因使用更高的抽象而感到内疚。毕竟,您正在使用String而不是char[]甚至byte[]? 我甚至建议在可能的情况下再走一步,并使用List接口。唯一降低一步的原因是出于性能原因。

使用更高级的集合抽象有许多优点。您可以添加装饰器,使列表只读,使其大小固定,检查进入或离开集合的项目或使用视图(请参见C#中的GetRange和Java中的subList)。

顺便提一下,ArrayList 应该总是基于原始数组,否则名称是错误的。通常情况下,操作的实现方式与使用原始数组时的预期相同。如果使用了链表,通常会直接命名为 LinkedList。这也是使用接口的优点之一:您可以随时更改对所用实现的决定。

使用集合的一些因素可能会使其操作不够灵活。其中一个警告是集合通常基于对象,语言在原始类型和对象类型之间有很大差距。有限的泛型也不是很有帮助。尽管如此,除非有很好的理由,我仍然推荐使用集合而不是数组。

对于原始值,您还可以考虑使用原始集合库,例如GNU Trove。不知道是否有类似于C#的东西。

《奇妙的编码冒险》写了一篇题为《有点害怕的数组》的文章。它是非常有趣的一篇阅读材料。

首先,如果你只打算处理特定类型,你不应该使用ArrayList。例如,如果你只期望一个byte数组,你应该只接受一个byte数组。

唯一一个我认为你可能想使用ArrayList的时候是代替List。

数组的大小是静态的,所以如果在设计期间知道大小,请使用数组。它应该可以更快地工作,但我自己没有测试过。如果需要频繁更改对象计数(从集合中添加或删除对象),请使用ArrayList或更好的.NET 2中的通用列表。它也更容易使用,所以如果性能不是至关重要的话,您总是可以使用List。

如果您需要一组基本类型,请使用Array以获得更好的性能,因为它将避免自动装箱和拆箱。但是只有在您预先知道所需大小的情况下才能这样做。

就像这样。

using System;
using System.Collections;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //ArrayList
            /*
             An ArrayList doesn t use a LinkedList as the internal data structure! .we can store any type of objects      
             */
            ArrayList list = new ArrayList();
            list.Add("1"); // not strongly type,you can enter any object types (int,string decimals, etc..)
            list.Add(1);
            list.Add(1.25);

            //Array
            /*
             must declare length.
             */
            string[] array = new string[3]; // you must declare object types
            array[0] = "1";
            //array[1] = 1; this get error becoz array is storngly typed. // this print empty value when you run it
            array[2] = "stongly typed";
            Console.WriteLine("------- ARRAYLIST ITEMS ---------");
            foreach (var i in list) {
                Console.WriteLine(i);
            }

            Console.WriteLine("--------- ARRAY ITEMS -----------");
            foreach (var i in array)
            {
                Console.WriteLine(i);
            }

            Console.ReadKey(); 
        }
    }
}




相关问题