服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#中数组Array,ArrayList,泛型List详细对比

C#中数组Array,ArrayList,泛型List详细对比

2021-11-26 14:07C#教程网 C#

关于数组Array,ArrayList,泛型List,简单的说数组就是值对象,它存储数据元素类型的值的一系列位置.Arraylist和list可以提供添加,删除,等操作的数据. 具体如何进行选择使用呢,我们来详细探讨下

在C#中数组Array,ArrayList,泛型List都能够存储一组对象,但是在开发中根本不知道用哪个性能最高,下面我们慢慢分析分析。

一、数组Array

数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。

Array 类是 C# 中所有数组的基类,它是在 System 命名空间中定义。

数组在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也非常简单。

Array数组具体用法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
 
namespace WebApp
{
  class Program
  {
    static void Main(string[] args)
    {
      //System.Array
      //1、数组[] 特定类型、固定长度
      string[] str1 = new string[3];
      str1[0] = "a";
      str1[1] = "b";
      str1[2] = "c";
      Console.WriteLine(str1[2]);
 
      string[] str2 = new string[] { "a", "b", "c" };
      Console.WriteLine(str2[0]);
 
      string[] str3 = { "a", "b", "c" };
      Console.WriteLine(str3[0]);
      //2、二维数组
      //int[,] intArray=new int[2,3]{{1,11,111},{2,22,222}};
      int[,] intArray = new int[2, 3];
      intArray[0, 0] = 1;
      intArray[0, 1] = 11;
      intArray[0, 2] = 111;
 
      intArray[1, 0] = 2;
      intArray[1, 1] = 22;
      intArray[1, 2] = 222;
      Console.WriteLine("{0},{1},{2}", intArray[0, 0], intArray[0, 1], intArray[0, 2]);
      Console.WriteLine("{0},{1},{2}", intArray[1, 0], intArray[1, 1], intArray[1, 2]);
 
      //3、多维数组
      int[, ,] intArray1 = new int[,,]
      {
        {{1, 1}, {11, 11}, {111, 111}},
        {{2, 2}, {22, 22}, {222, 222}},
        {{3, 3}, {33, 33}, {333, 333}}
      };
      Console.WriteLine("{0},{1},{2},{3},{4},{5}", intArray1[0, 0, 0], intArray1[0, 0, 1], intArray1[0, 1, 0], intArray1[0, 1, 1],
        intArray1[0, 2, 0], intArray1[0, 2, 1]);
      Console.WriteLine("{0},{1},{2},{3},{4},{5}", intArray1[1, 0, 0], intArray1[1, 0, 1], intArray1[1, 1, 0], intArray1[1, 1, 1],
        intArray1[1, 2, 0], intArray1[1, 2, 1]);
      Console.WriteLine("{0},{1},{2},{3},{4},{5}", intArray1[2, 0, 0], intArray1[2, 0, 1], intArray1[2, 1, 0], intArray1[2, 1, 1],
        intArray1[2, 2, 0], intArray1[2, 2, 1]);
 
      //4、交错数组即数组的数组
      int[][] intArray2 = new int[4][];
      intArray2[0] = new int[] { 1 };
      intArray2[1] = new int[] { 2, 22 };
      intArray2[2] = new int[] { 3, 33, 333 };
      intArray2[3] = new int[] { 4, 44, 444,4444 };
      for (int i = 0; i < intArray2.Length; i++)
      {
        for (int j = 0; j < intArray2[i].Length; j++)
        {
          Console.WriteLine("{0}", intArray2[i][j]);
        }
      }
 
 
      Console.ReadKey();
    }
  }
}

数组虽然存储检索数据很快,但是也有一些缺点:

1、在声明数组的时候必须指定数组的长度,如果不清楚数组的长度,就会变得很麻烦。

2、数组的长度太长,会造成内存浪费;太短会造成数据溢出的错误。

3、在数组的两个数据间插入数据是很麻烦的

更多参考微软官方文档:Array 类 (System)

二、ArrayList

既然数组有很多缺点,C#就提供了ArrayList对象来克服这些缺点。

ArrayList是在命名空间System.Collections下,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索。

ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的。因此在声明ArrayList对象时并不需要指定它的长度。

ArrayList 的默认初始容量为 0。随着元素添加到 ArrayList 中,容量会根据需要通过重新分配自动增加。可通过调用 TrimToSize 或通过显式设置 Capacity 属性减少容量。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Collections;
public class SamplesArrayList {
 
  public static void Main() {
 
   ArrayList myAL = new ArrayList();
   myAL.Add("Hello");
   myAL.Add("World");
   myAL.Add("!");
 
   Console.WriteLine( "myAL" );
   Console.WriteLine( "  Count:  {0}", myAL.Count );
   Console.WriteLine( "  Capacity: {0}", myAL.Capacity );
   Console.Write( "  Values:" );
   PrintValues( myAL );
  }
 
  public static void PrintValues( IEnumerable myList ) {
   foreach ( Object obj in myList )
     Console.Write( "  {0}", obj );
   Console.WriteLine();
   Console.ReadKey();
  }
 
}

运行结果:

 

ArrayList解决了数组中所有的缺点,但是在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。尤其是装箱操作,例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ArrayList list = new ArrayList();
 
//add
list.Add("joye.net");
list.Add(27);
 
//update
list[2] = 28;
 
//delete
list.RemoveAt(0);
 
//Insert
list.Insert(0, "joye.net1");

在List中,先插入了字符串joye.net,而且插入了int类型27。这样在ArrayList中插入不同类型的数据是允许的。因为ArrayList会把所有插入其中的数据当作为object类型来处理,在使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的。

更多参考微软官方ArrayList文档:ArrayList 类 (System.Collections)

三、泛型List<T>

由于ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。

List 类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现 IList 泛型接口,大部分用法都与ArrayList相似。

List<T> 是类型安全的,在声明List集合时,必须为其声明List集合内数据的对象类型。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
 
public class Example
{
  public static void Main()
  {
    List<string> dinosaurs = new List<string>();
 
    Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);
 
    dinosaurs.Add("Tyrannosaurus");
    dinosaurs.Add("Amargasaurus");
    dinosaurs.Add("Mamenchisaurus");
    dinosaurs.Add("Deinonychus");
    dinosaurs.Add("Compsognathus");
 
    Console.WriteLine();
    foreach(string dinosaur in dinosaurs)
    {
      Console.WriteLine(dinosaur);
    }
 
    Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);
    Console.WriteLine("Count: {0}", dinosaurs.Count);
 
    Console.WriteLine("\nContains(\"Deinonychus\"): {0}",
      dinosaurs.Contains("Deinonychus"));
 
    Console.WriteLine("\nInsert(2, \"Compsognathus\")");
    dinosaurs.Insert(2, "Compsognathus");
 
    Console.WriteLine();
    foreach(string dinosaur in dinosaurs)
    {
      Console.WriteLine(dinosaur);
    }
 
    Console.WriteLine("\ndinosaurs[3]: {0}", dinosaurs[3]);
 
    Console.WriteLine("\nRemove(\"Compsognathus\")");
    dinosaurs.Remove("Compsognathus");
 
    Console.WriteLine();
    foreach(string dinosaur in dinosaurs)
    {
      Console.WriteLine(dinosaur);
    }
 
    dinosaurs.TrimExcess();
    Console.WriteLine("\nTrimExcess()");
    Console.WriteLine("Capacity: {0}", dinosaurs.Capacity);
    Console.WriteLine("Count: {0}", dinosaurs.Count);
 
    dinosaurs.Clear();
    Console.WriteLine("\nClear()");
    Console.WriteLine("Capacity: {0}", dinosaurs.Capacity);
    Console.WriteLine("Count: {0}", dinosaurs.Count);
  }
}

如果声明List集合内数据的对象类型是string,然后往List集合中插入int类型的111,IDE就会报错,且不能通过编译。显然这样List<T>是类型安全的。

对返回结果集再封装:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ResultDTO<T>
{
  public T Data { get; set; }
  public string Code { get; set; }
  public string Message { get; set; }
}
 
    var data = new CityEntity();
    return new ResultDTO<CityEntity> { Data = data, Code = "1", Message = "sucess"};
 
    var data2 = new List<CityEntity>();
    return new ResultDTO<List<CityEntity>> { Data = data2, Code = "1", Message = "sucess" };
 
    var data1 = 1;
    return new ResultDTO<int> { Data = data1, Code = "1", Message = "sucess" };

更多参考微软官方文档:List泛型类

四、总结

1、数组的容量固定,而ArrayList或List<T>的容量可根据需要自动扩充。

2、数组可有多个维度,而 ArrayList或 List< T> 始终只有一个维度。(可以创建数组列表或列表的列表)

3、特定类型的数组性能优于 ArrayList的性能(不包括Object,因为 ArrayList的元素是 Object ,在存储或检索值类型时通常发生装箱和取消装箱操作)。

4、 ArrayList 和 List<T>基本等效,如果List< T> 类的类型T是引用类型,则两个类的行为是完全相同的。如果T是值类型,需要考虑装箱和拆箱造成的性能损耗。List<T> 是类型安全。

延伸 · 阅读

精彩推荐
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28