在c#中,数组列表和List<>有什么区别?

是不是只有List<>有类型而ArrayList没有?


当前回答

性能已经在几个答案中被提到作为一个区分因素,但是要解决“数组列表有多慢?”和“为什么整体上更慢?”,请看下面的内容。

当使用值类型作为元素时,ArrayList的性能会急剧下降。考虑简单地添加元素的情况。由于装箱正在进行——因为ArrayList的Add只接受对象参数——垃圾收集器被触发执行比List<T>更多的工作。

时差是多少?至少比List<T>慢几倍。看看在数组列表中添加10mil int值和List<T>的代码会发生什么:

在“均值”列(黄色突出显示)中,这是5倍的运行时间差异。还要注意为每个gc执行的垃圾收集数量的差异,用红色突出显示(每1000次运行没有gc)。

使用分析器快速查看发生了什么,这表明大部分时间都花在了gc上,而不是实际添加元素。下面的棕色条表示阻塞垃圾收集器活动:

我在这里https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/写了一篇关于上述ArrayList场景的详细分析。

Jeffrey Richter的《CLR via c#》中也有类似的发现。第12章(泛型):

[…] When I compile and run a release build (with optimizations turned on) of this program on my computer, I get the following output. 00:00:01.6246959 (GCs= 6) List<Int32> 00:00:10.8555008 (GCs=390) ArrayList of Int32 00:00:02.5427847 (GCs= 4) List<String> 00:00:02.7944831 (GCs= 7) ArrayList of String The output here shows that using the generic List algorithm with the Int32 type is much faster than using the non-generic ArrayList algorithm with Int32. In fact, the difference is phenomenal: 1.6 seconds versus almost 11 seconds. That’s ~7 times faster! In addition, using a value type (Int32) with ArrayList causes a lot of boxing operations to occur, which results in 390 garbage collections. Meanwhile, the List algorithm required 6 garbage collections.

其他回答

我认为,ArrayList和List<T>之间的区别是:

List<T>, where T is value-type is faster than ArrayList. This is because List<T> avoids boxing/unboxing (where T is value-type). Many sources say - usually ArrayList used just for backward compatibility. (is not a real difference, but i think it is important note). Reflection is easier with nongeneric ArrayList then List<T> ArrayList has IsSynchronized property. So, It is easy to create and use syncronised ArrayList. I didin't found IsSynchronized property for List<T>. Also Keep in mind this type of synchronization is relatively inefficient, msdn): var arraylist = new ArrayList(); var arrayListSyncronized = ArrayList.Synchronized(arraylist Console.WriteLine($"syncronized {arraylist.IsSynchronized}"); Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}"); var list = new List<object>(); var listSyncronized = ArrayList.Synchronized(list); Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop ArrayList has ArrayList.SyncRoot property which can be used for syncronisation (msdn). List<T> hasn't SyncRoot property, so in the following construction you need to use some object if you use List<T>: ArrayList myCollection = new ArrayList(); lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal { foreach (object item in myCollection) { // ... } }

ArrayList不是类型安全的,而List<T>是类型安全的。简单:)。

再加上以上几点。在64位操作系统中使用ArrayList占用的内存是32位操作系统的2倍。同时,泛型列表list <T>占用的内存比ArrayList少得多。

例如,如果我们在32位中使用一个19MB的数组列表,那么在64位中它将占用39MB。但是如果你有一个32位的8MB的通用列表list <int>,它在64位只需要8.1MB,这与ArrayList相比相差了481%。

来源:数组列表与通用列表的基本类型和64位

简单的答案是,

数组列表是非泛型的

它是一个对象类型,因此您可以在其中存储任何数据类型。 可以在数组列表中存储任意值(值类型或引用类型),例如string、int、employee和object。(注意,) 装箱和开箱将会发生。 不类型安全。 它更老。

列表是通用的

它是类型的类型,因此您可以在运行时指定T。 根据声明,您只能存储类型为T的值(字符串或int或employee或object)。(注意或) 装箱和开箱不会发生。 类型安全。 它更新。

例子:

ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();

arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());


list.Add(1);
list.Add("String");                 // Compile-time Error
list.Add(new object());             // Compile-time Error

请阅读微软官方文档:https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/

注意:在理解它们的区别之前,您应该了解泛型:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/

使用“List”可以防止强制转换错误。它对于避免运行时强制转换错误非常有用。

例子:

在这里(使用ArrayList),您可以编译这段代码,但稍后会看到一个执行错误。

    // Create a new ArrayList


    System.Collections.ArrayList mixedList = new System.Collections.ArrayList();


    // Add some numbers to the list
    mixedList.Add(7);
    mixedList.Add(21);


    // Add some strings to the list
    mixedList.Add("Hello");
    mixedList.Add("This is going to be a problem");




    System.Collections.ArrayList intList = new System.Collections.ArrayList();
    System.Collections.ArrayList strList = new System.Collections.ArrayList();


    foreach (object obj in mixedList)
    {
        if (obj.GetType().Equals(typeof(int)))
        {
            intList.Add(obj);
        }
        else if (obj.GetType().Equals(typeof(string)))
        {
            strList.Add(obj);
        }
        else
        {
            // error.
        }
    }