软件编程
位置:首页>> 软件编程>> C#编程>> C#中List<T>存放元素的工作机制

C#中List<T>存放元素的工作机制

作者:Darren?Ji  发布时间:2022-09-29 16:31:23 

标签:C#,List,存放,元素

List<T>是怎么存放元素?我们扒一段List<T>的一段源码来一窥究竟。

using System;
using System.Diagnostic;
using System.Collections.ObjectModel;
using System.Security.Permissions;

namespace System.Collections.Generic
{
   ...
   [Serializable()]
   public class List<t> : IList<t>, System.Collections.IList
   {
       private const int _defaultCapacity = 4;
       private T[] _items; //List<T>内部是依靠数组_items存放数据的
       private int _size; //数组的长度
       private int _version;
       [NoSerialized]
       private Object _syncRoot;
       static T[] _emptyArray = new T[0];

//无参数构造函数 把_items设置成一个空的数组
       public List()
       {
           _items = _emptyArray;
       }

//此构造函数 给_items数组一个初始容量
       public List(int capacity)
       {
           ...
           items = new T[capaicty];
       }

//此构造函数 把集合类型参数拷贝给_items数组
       public List(IEnumerable<t> collection)
       {
           ...
           ICollection<t> c = collection as ICollection<t>;
           if(c != null)
           {
               int count = c.Count; //把构造函数集合类型参数的长度赋值给临时变量count
               _items = new T[count]; //List<T>内部维护的_items数组的长度和构造函数集合类型参数的长度一致
               c.CopyTo(_items, 0); //把构造函数集合的所有元素拷贝到_items数组中去
               _size = count; //_items数组的长度就是构造函数集合类型参数的长度
           }
           else
           {
               _size = 0;
               _items = new T[_defaultCapacity];
               ...
           }
       }

//通过设置这个属性,改变List<t>内部维护的_items数组的长度
       public int Capacity
       {
           get {return _items.Length; }
           set {
               if(value != _items.Length){ //如果当前赋值和List<t>维护的内部数组_items长度不一致
                   if(value < _size){
                       //TODO: 处理异常
                   }
                   if(value > 0){
                       T[] newItems = new T[value]; //创建一个临时的、新的数组,长度为新的赋值
                       if(_size > 0){
                           //把临时的、新的数组拷贝给List<t>内部维护的数组_items,注意,这时_items的长度为新的赋值
                           Array.Copy(_items, 0, newItems, 0, _size);
                       }
                   } else {
                       _items = _emptyArray;
                   }
               }
           }
       }

public void Add(T item)
       {
           if(_size == _items.Length) EnsureCapacity(_size + 1);
           _items[_size++] = item;
           ...
       }

//确保List<t>内部维护的_items数组的长度至少是给定的值
       //如果_items数组原先的长度比给定的值小,就让_items数组的长度设置为原先的长度的2倍
       privat void EnsureCapacity(int min)
       {
           if(_items.Length < min){
                int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Legnth * 2;
                if(newCapacity < min) newCapacity = min;
                Capacity = newCapacity;
           }
       }

}
}

由此可见,向List<T>中存放元素的大致过程是这样的:

  • List<T>内部维护着一个数组_items,用来存放T类型的元素。

  • 当有新的T类型元素存放进来,即调用Add(T item)方法。

  • Add(T item)方法内部调用EnsureCapacity(int min)方法确保List<T>的Capaicty属性值至少在原先长度上加1,最多是原先长度的2倍。

  • 在给Capacity赋值的过程中,对_items的长度进行了扩容。

  • 扩容后,再把新的T类型元素存放进来。

简单地说:

当有新的元素存放到List<T>中时,List<T>先对其维护的内部数组进行扩容,然后再把新元素放进来。

来源:https://www.cnblogs.com/darrenji/p/3843749.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com