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

 更新时间:2016年06月17日 10:03:18   投稿:hebedich  
关于数组Array,ArrayList,泛型List,简单的说数组就是值对象,它存储数据元素类型的值的一系列位置.Arraylist和list可以提供添加,删除,等操作的数据. 具体如何进行选择使用呢,我们来详细探讨下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

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

一、数组Array

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

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

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

Array数组具体用法:

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 属性减少容量。

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

      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集合内数据的对象类型。

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>是类型安全的。

对返回结果集再封装:

  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#设计模式之策略模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 一道关于C#参数传递的面试题分析

    一道关于C#参数传递的面试题分析

    这篇文章主要介绍了一道关于C#参数传递的面试题,实例分析了C#参数传递的相关使用技巧,需要的朋友可以参考下
    2015-05-05
  • c#如何利用定时器自动备份数据库详解

    c#如何利用定时器自动备份数据库详解

    在开发过程当中,你一定遇到文件损坏活或丢失的烦恼,而每天备份又很麻烦,你只要设置每天备份的时间,并将程序加入启动项中,就可以自动完成备份,这篇文章主要给大家介绍了关于c#如何利用定时器自动备份数据库的相关资料,需要的朋友可以参考下
    2021-10-10
  • 适用于WebForm Mvc的Pager分页组件C#实现

    适用于WebForm Mvc的Pager分页组件C#实现

    这篇文章主要为大家分享了适用于WebForm Mvc的Pager分页组件,由C#实现,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • C#使用文件流FileStream和内存流MemoryStream操作底层字节数组byte[]

    C#使用文件流FileStream和内存流MemoryStream操作底层字节数组byte[]

    这篇文章介绍了C#使用文件流FileStream和内存流MemoryStream操作底层字节数组byte[]的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#中使用Cache框架快速实现Cache操作

    C#中使用Cache框架快速实现Cache操作

    这篇文章介绍了C#中使用Cache框架快速实现Cache操作的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#基于纯数学方法递归实现货币数字转换中文功能详解

    C#基于纯数学方法递归实现货币数字转换中文功能详解

    这篇文章主要介绍了C#基于纯数学方法递归实现货币数字转换中文功能,涉及C#针对字符串的遍历、转换与数学运算相关操作技巧,需要的朋友可以参考下
    2017-02-02
  • C#文字换行的实现方法

    C#文字换行的实现方法

    这篇文章主要介绍了C#文字换行的实现方法,通过自定义函数实现针对特定字符串的换行长度处理,是比较实用的技巧,对于C#的深入学习具有一定的借鉴价值,需要的朋友可以参考下
    2014-12-12
  • Unity3D Shader实现动态屏幕遮罩

    Unity3D Shader实现动态屏幕遮罩

    这篇文章主要为大家详细介绍了Unity3D Shader实现动态屏幕遮罩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Windows中使用C#为文件夹和文件编写密码锁的示例分享

    Windows中使用C#为文件夹和文件编写密码锁的示例分享

    这篇文章主要介绍了Windows中使用C#为文件夹和文件编写密码锁的示例分享,特别是文件锁可以针对各种类型的文件输入密码进行加密解密,非常实用,需要的朋友可以参考下
    2016-03-03

最新评论

?


http://www.vxiaotou.com