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