ArrayList vs List<>在C#中

时间:2010-02-22 08:36:55

标签: c# .net list generics arraylist

C#中ArrayListList<>之间有什么区别?

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

13 个答案:

答案 0 :(得分:481)

是的,差不多。 List<T>是一个通用类。它支持存储特定类型的值,而无需转换到object或从T转换(当ArrayListArrayList情况下object是值类型时,会产生装箱/拆箱开销。 List<T>只存储IEnumerable<T>个引用。作为通用集合,Cast实现了通用OfType接口,可以在LINQ中轻松使用(无需任何ArrayListList<T>调用)。

ArrayList属于C#没有泛型的日子。它被弃用,而不是{{1}}。您不应在以.NET&gt; = 2.0为目标的新代码中使用{{1}},除非您必须与使用它的旧API进行交互。

答案 1 :(得分:94)

使用List<T>可以防止出现错误。避免运行时转换错误非常有用。

示例:

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

ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
 total += num; //-->Runtime Error
}

如果您使用List,则可以避免这些错误:

List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
 total += num;
}

参考: MSDN

答案 2 :(得分:23)

添加到以上几点。在64位操作系统中使用ArrayList占用的内存比在32位操作系统中使用的内存大2倍。同时,通用列表List<T>将使用比ArrayList低得多的内存。

例如,如果我们在32位中使用19MB的ArrayList,则在64位中需要39MB。但是如果32位的通用列表List<int>为8MB,那么64位只需要8.1MB,与ArrayList相比,差异为481%。

来源:ArrayList’s vs. generic List for primitive types and 64-bits

答案 3 :(得分:18)

要添加的另一个区别是线程同步。

  

ArrayList通过Synchronized属性提供一些线程安全性,该属性返回集合周围的线程安全包装器。包装器通过在每次添加或删除操作时锁定整个集合来工作。因此,尝试访问集合的每个线程必须等待轮到一个锁。这不可扩展,并且可能导致大型集合的性能显着下降。

     

List<T>不提供任何线程同步;用户代码必须在多个线程上同时添加或删除项目时提供所有同步。

此处有更多信息{{3}}

答案 4 :(得分:6)

简单回答是,

ArrayList是非通用的

  • 它是一个对象类型,因此您可以将任何数据类型存储到其中。
  • 您可以在ArrayList中存储任何值(值类型或引用类型),如string,int,employee和object。 (注意和)
  • 拳击和拆箱将会发生。
  • 不安全。
  • 年纪大了。

列表是通用的

  • 这是Type of Type,因此您可以在运行时指定T.
  • 您可以根据声明存储Type T(string或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

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

enter image description here

注意:在了解差异之前,您应该了解泛型:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/

答案 5 :(得分:3)

ArrayList是不同类型数据的集合,而List<>是其自身类型的相似类型的集合。

答案 6 :(得分:3)

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

答案 7 :(得分:1)

我认为ArrayListList<T>之间的差异是:

  1. List<T>,其中T是值类型比ArrayList快。这是 因为List<T>避免装箱/拆箱(其中T是值型)。
  2. 许多消息来源说 - 通常ArrayList仅用于落后 兼容性。 (这不是真正的区别,但我认为是 重要提示)。
  3. 使用非通用ArrayList然后List<T>
  4. ,反思更容易
  5. ArrayList拥有IsSynchronized属性。所以,很容易 创建和使用同步ArrayList。我找不到IsSynchronized的{​​{1}}属性。另外请记住,这种类型的同步效率相对较低,msdn):

    List<T>
  6. 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属性,可用于同步(msdn)。 ArrayList.SyncRoot没有List<T>属性,所以 如果使用SyncRoot

    ,则需要使用以下构造
    List<T>

答案 8 :(得分:0)

如.NET Framework documentation

中所述
  

我们不建议您将ArrayList类用于新   发展。相反,我们建议您使用通用的List<T>   类。 ArrayList类旨在容纳异构对象   对象的集合。但是,它并不总是提供最好的   性能。相反,我们建议以下内容:

     
      
  • 对于异构对象集合,请使用List<Object>(在C#中)或List(Of Object)(在Visual Basic中)类型。
  •   
  • 对于同类对象,请使用List<T>类。
  •   

另请参见Non-generic collections shouldn't be used

table shows how the non-generic collection types can be replaced by their generic counterparts

答案 9 :(得分:0)

性能已经在几个答案中作为区别因素提到了,但是要解决“ ArrayList慢多少?”和“ 为什么整体速度慢” ?”,请在下面看看。

每当将值类型用作元素时,ArrayList的性能都会急剧下降。考虑简单添加元素的情况。由于装箱正在进行-ArrayList的“添加”仅接受object个参数-垃圾收集器被触发执行比List<T>还要多的工作。

时差是多少?至少比List<T>慢几倍。只需看一看将1000万个int值添加到ArrayListList<T>的代码中会发生什么: enter image description here

在“平均值”列中,运行时间差异为 5倍,以黄色突出显示。另请注意,每个垃圾收集完成的数量之间的差异以红色突出显示(GC数量/ 1000次运行)。

使用探查器快速查看发生的情况表明,大部分时间都花在了GC上,而不是实际添加元素。下面的棕色条表示阻止垃圾收集器的活动: enter image description here

我在https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/上详细分析了上述ArrayList场景的情况。

类似的发现在Jeffrey Richter的“通过C#进行CLR”中。从第12章(泛型)开始:

  

[…]当我编译并运行发布版本时(已启用优化   在我计算机上的该程序上,我得到以下输出。

     

00:00:01.6246959(GCs = 6)列表
   00:00:10.8555008(GCs = 390)Int32的ArrayList
  00:00:02.5427847(GCs = 4)列表
  00:00:02.7944831(GCs = 7)字符串的ArrayList

     

这里的输出显示   使用具有Int32类型的通用List算法的好处是   比在Int32中使用非通用ArrayList算法要快。在   实际上,差异是惊人的:1.6秒与将近11秒   秒。快了约7倍!!另外,使用值类型   (Int32)与ArrayList会导致发生很多装箱操作,   导致390个垃圾回收。同时,清单   该算法需要6个垃圾回收。

答案 10 :(得分:-2)

使用&#34; List&#34;你可以防止出现错误。避免运行时转换错误非常有用。

示例:

这里(使用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.
        }
    }

答案 11 :(得分:-3)

对我来说,了解你的数据。如果我继续在效率的基础上扩展我的代码,我将不得不选择List选项作为解密我的数据的方式,而不是总是想知道类型的不必要的步骤,尤其是“自定义类型”。如果机器了解差异并且可以确定我实际处理的是什么类型的数据,那么为什么我要阻止并且浪费时间通过“IF THEN ELSE”确定的回转?我的理念是让机器为我而不是我在机器上工作?了解不同目标代码命令的独特差异对于使代码有效有很大帮助。

汤姆约翰逊 (一次进入......一次退出)

答案 12 :(得分:-6)

这不仅仅是区别。 ArrayList成员可以像普通数组一样通过索引访问,并且ArrayList成员可以很容易地按直接和反向顺序排序,并且两个ArrayList可以很容易地合并,而简单List就不是这种情况。

了解更多信息

http://www.cirvirlab.com/index.php/c-sharp-code-examples/112-c-sharp-arraylist-example.html