C#中List<T>存放元素的工作機制
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>內(nèi)部是依靠數(shù)組_items存放數(shù)據(jù)的
private int _size; //數(shù)組的長度
private int _version;
[NoSerialized]
private Object _syncRoot;
static T[] _emptyArray = new T[0];
//無參數(shù)構(gòu)造函數(shù) 把_items設置成一個空的數(shù)組
public List()
{
_items = _emptyArray;
}
//此構(gòu)造函數(shù) 給_items數(shù)組一個初始容量
public List(int capacity)
{
...
items = new T[capaicty];
}
//此構(gòu)造函數(shù) 把集合類型參數(shù)拷貝給_items數(shù)組
public List(IEnumerable<t> collection)
{
...
ICollection<t> c = collection as ICollection<t>;
if(c != null)
{
int count = c.Count; //把構(gòu)造函數(shù)集合類型參數(shù)的長度賦值給臨時變量count
_items = new T[count]; //List<T>內(nèi)部維護的_items數(shù)組的長度和構(gòu)造函數(shù)集合類型參數(shù)的長度一致
c.CopyTo(_items, 0); //把構(gòu)造函數(shù)集合的所有元素拷貝到_items數(shù)組中去
_size = count; //_items數(shù)組的長度就是構(gòu)造函數(shù)集合類型參數(shù)的長度
}
else
{
_size = 0;
_items = new T[_defaultCapacity];
...
}
}
//通過設置這個屬性,改變List<t>內(nèi)部維護的_items數(shù)組的長度
public int Capacity
{
get {return _items.Length; }
set {
if(value != _items.Length){ //如果當前賦值和List<t>維護的內(nèi)部數(shù)組_items長度不一致
if(value < _size){
//TODO: 處理異常
}
if(value > 0){
T[] newItems = new T[value]; //創(chuàng)建一個臨時的、新的數(shù)組,長度為新的賦值
if(_size > 0){
//把臨時的、新的數(shù)組拷貝給List<t>內(nèi)部維護的數(shù)組_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>內(nèi)部維護的_items數(shù)組的長度至少是給定的值
//如果_items數(shù)組原先的長度比給定的值小,就讓_items數(shù)組的長度設置為原先的長度的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>內(nèi)部維護著一個數(shù)組_items,用來存放T類型的元素。
- 當有新的T類型元素存放進來,即調(diào)用Add(T item)方法。
- Add(T item)方法內(nèi)部調(diào)用EnsureCapacity(int min)方法確保List<T>的Capaicty屬性值至少在原先長度上加1,最多是原先長度的2倍。
- 在給Capacity賦值的過程中,對_items的長度進行了擴容。
- 擴容后,再把新的T類型元素存放進來。
簡單地說:
當有新的元素存放到List<T>中時,List<T>先對其維護的內(nèi)部數(shù)組進行擴容,然后再把新元素放進來。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內(nèi)容請查看下面相關鏈接
相關文章
C#實現(xiàn)Windows Form調(diào)用R進行繪圖與顯示的方法
眾所周知R軟件功能非常強大,可以很好的進行各類統(tǒng)計,并能輸出圖形。下面介紹一種R語言和C#進行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細,需要的朋友可以參考下。2017-02-02
C# 添加對System.Configuration.dll文件的引用操作
這篇文章主要介紹了C# 添加對System.Configuration.dll文件的引用操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
淺析C#?AsyncLocal如何在異步間進行數(shù)據(jù)流轉(zhuǎn)
在異步編程中,處理異步操作之間的數(shù)據(jù)流轉(zhuǎn)是一個比較常用的操作,C#異步編程提供了一個強大的工具來解決這個問題,那就是AsyncLocal,下面我們就來看看AsyncLocal的原理和用法吧2023-08-08
C#利用System.Threading.Thread.Sleep即時輸出信息的詳解
本篇文章是對C#利用System.Threading.Thread.Sleep即時輸出信息進行了詳細的分析介紹,需要的朋友參考下2013-06-06
c# winform 關閉窗體時同時結(jié)束線程實現(xiàn)思路
th.IsBackground = true解決線程問題,意思就是把線程設置為后臺線程,感興趣的朋友可以多了解下,如何有什么妙招還請多多指導哈2013-02-02

