欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c#系列 list詳情

 更新時(shí)間:2021年10月25日 09:25:02   作者:敖毛毛  
這篇文章主要介紹了c#系列 list,list 本質(zhì)是一個(gè)數(shù)組,。就跟我們操作系統(tǒng)一樣,提前申請(qǐng)內(nèi)存大小。所以我們程序一般都有一個(gè)申請(qǐng)內(nèi)存,實(shí)際使用內(nèi)存,內(nèi)存碎片這幾個(gè)概念,下面?zhèn)z看文章詳細(xì)內(nèi)容吧

這里以list為介紹:

private static readonly T[] s_emptyArray = new T[0];
public List()
{
  this._items = List<T>.s_emptyArray;
}

list 本質(zhì)是一個(gè)數(shù)組。

同樣我們可以指定容量,如果我們知道了我們大概需要多少數(shù)據(jù),那么我們可以指定一下,這樣避免了resize的損耗。

就跟我們操作系統(tǒng)一樣,提前申請(qǐng)內(nèi)存大小。所以我們程序一般都有一個(gè)申請(qǐng)內(nèi)存,實(shí)際使用內(nèi)存,內(nèi)存碎片這幾個(gè)概念。

添加也是很簡(jiǎn)單哈

public void Add(T item)
{
  ++this._version;
  T[] items = this._items;
  int size = this._size;
  if ((uint) size < (uint) items.Length)
  {
 this._size = size + 1;
 items[size] = item;
  }
  else
 this.AddWithResize(item);
}

判斷是否滿了,如果沒(méi)滿直接存到數(shù)組里面去,如果滿了,那么resize一下。

看下resize:

private void AddWithResize(T item)
{
  int size = this._size;
  this.EnsureCapacity(size + 1);
  this._size = size + 1;
  this._items[size] = item;
}


然后看一下擴(kuò)容步驟:

private void EnsureCapacity(int min)
{
  if (this._items.Length >= min)
 return;
  int num = this._items.Length == 0 ? 4 : this._items.Length * 2;
  if ((uint) num > 2146435071U)
 num = 2146435071;
  if (num < min)
 num = min;
  this.Capacity = num;
}

首先在做了一次判斷,判斷是否容量夠用,所以是size+1。

if (this._items.Length >= min)
 return;


這里就有人問(wèn)了外面不是判斷了,為什么里面還有判斷。

這個(gè)就是一些人喜歡談性能的地方了,認(rèn)為多此一舉,如果里面不判斷那么就不是一個(gè)成熟的方法,提現(xiàn)不出方法的封閉性,因?yàn)榉椒ǖ淖饔檬侵蛥?shù)打交道,外面是什么其實(shí)是不管的。

那么可以看出,一開(kāi)始是4,然后后面就是翻倍了。

然后重點(diǎn)看下:

 this.Capacity = num;


這個(gè)this.Capacity 并不是普通的變量,而是一個(gè)屬性哈,不然你都納悶它是怎么擴(kuò)容了。

public int Capacity
{
 get => _items.Length;
 set
 {
  if (value < _size)
  {
   ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
  }

  if (value != _items.Length)
  {
   if (value > 0)
   {
    T[] newItems = new T[value];
    if (_size > 0)
    {
     Array.Copy(_items, newItems, _size);
    }
    _items = newItems;
   }
   else
   {
    _items = s_emptyArray;
   }
  }
 }
}

首先判斷了不能縮容,如果縮容直接異常,其次我們注意道這個(gè)Capacity piblic的,也就是說(shuō)我們?cè)谕獠烤涂梢灾苯诱{(diào)用。

后面邏輯就很簡(jiǎn)單創(chuàng)建一個(gè)新的數(shù)組,然后復(fù)制就ok了,然后重新賦值_items。

那么來(lái)看一下remove吧:

public bool Remove(T item)
{
 int index = IndexOf(item);
 if (index >= 0)
 {
  RemoveAt(index);
  return true;
 }

 return false;
}

首先是找到其位置:

public int IndexOf(T item)
 => Array.IndexOf(_items, item, 0, _size);

int IList.IndexOf(object? item)
{
 if (IsCompatibleObject(item))
 {
  return IndexOf((T)item!);
 }
 return -1;
}

可以看一下這個(gè)IsCompatibleObject,還是很有趣的。

private static bool IsCompatibleObject(object? value)
{
 // Non-null values are fine.  Only accept nulls if T is a class or Nullable<U>.
 // Note that default(T) is not equal to null for value types except when T is Nullable<U>.
 return (value is T) || (value == null && default(T) == null);
}

從這個(gè)說(shuō)明,其實(shí)我們是可以傳空對(duì)象的。

static void Main(string[] args)
{
 List<object> lists = new List<object>();

 lists.Add(null);

 Console.WriteLine(lists.Count);

 lists.Remove(null);
 Console.ReadLine();
}



那么來(lái)看一下removeat吧:

public void RemoveAt(int index)
{
 if ((uint)index >= (uint)_size)
 {
  ThrowHelper.ThrowArgumentOutOfRange_IndexException();
 }
 _size--;
 if (index < _size)
 {
  Array.Copy(_items, index + 1, _items, index, _size - index);
 }
 if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
 {
  _items[_size] = default!;
 }
 _version++;
}

這里可以看出list的remove操作還是性能損耗很大的,尤其是大的list。

這里有沒(méi)有注意道一個(gè)_version,這個(gè)有什么作用呢?

當(dāng)遍歷的時(shí)候我們就用的到

internal Enumerator(List<T> list)
{
 _list = list;
 _index = 0;
 _version = list._version;
 _current = default;
}

public void Dispose()
{
}

public bool MoveNext()
{
 List<T> localList = _list;

 if (_version == localList._version && ((uint)_index < (uint)localList._size))
 {
  _current = localList._items[_index];
  _index++;
  return true;
 }
 return MoveNextRare();
}

private bool MoveNextRare()
{
 if (_version != _list._version)
 {
  ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
 }

 _index = _list._size + 1;
 _current = default;
 return false;
}

重點(diǎn)看上面的list,上面表面了,當(dāng)我們使用foreach 進(jìn)行遍歷的時(shí)候,如果我們進(jìn)行了刪除或者添加,那么_version就會(huì)發(fā)生變化,那么可想而知會(huì)拋出異常。

例子:

static void Main(string[] args)
{
 List<object> lists = new List<object>();

 lists.Add("123456");

 lists.Add("1231246");

 lists.Add("dsadadsads");

 lists.Add("eqewqew");

 foreach (var item in lists)
 {
  if (item.ToString() == "1231246")
  {
   lists.Remove(item);
  }
 }

 Console.ReadLine();
}

然后就會(huì)拋出異常了。

那么這里就不介紹find了,find 就是遍歷數(shù)組,找出是否相等。

哦,對(duì)了講另外一個(gè)故事。

public int Count => _size;


count-1 就是當(dāng)前插入的位置。

那么如果你想刪除某個(gè)元素的時(shí)候,那么你可以進(jìn)行removeat 刪除,這樣避免了find。

那么非常值得注意的是如果刪除了其他元素,如果那么元素的位置小于你記錄的位置,那么應(yīng)該是位置進(jìn)行減一。

到此這篇關(guān)于c#系列 list詳情的文章就介紹到這了,更多相關(guān)c#系列 list內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#.NET獲取撥號(hào)連接的寬帶連接方法

    C#.NET獲取撥號(hào)連接的寬帶連接方法

    這篇文章主要介紹了C#.NET獲取撥號(hào)連接的寬帶連接方法,實(shí)例演示了一個(gè)C#封裝的ADSL撥號(hào)連接類(lèi)及其使用方法,需要的朋友可以參考下
    2015-06-06
  • C#中string.format用法詳解

    C#中string.format用法詳解

    這篇文章主要介紹了C#中string.format用法,以實(shí)例形式較為詳細(xì)的講述了string.format格式化的各種用法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-11-11
  • C# jpg縮略圖函數(shù)代碼

    C# jpg縮略圖函數(shù)代碼

    生成jpg縮略圖字節(jié),本人的小軟件中需要用到的功能,所以自己做了一個(gè)函數(shù),和大家分享 為什么要生成字節(jié)而不是文件,這是為了方便后續(xù)處理啦^_^
    2011-06-06
  • C#獲取指定年份第一個(gè)星期一具體日期的方法

    C#獲取指定年份第一個(gè)星期一具體日期的方法

    這篇文章主要介紹了C#獲取指定年份第一個(gè)星期一具體日期的方法,涉及C#日期與字符串操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • 基于C#后臺(tái)調(diào)用跨域MVC服務(wù)及帶Cookie驗(yàn)證的實(shí)現(xiàn)

    基于C#后臺(tái)調(diào)用跨域MVC服務(wù)及帶Cookie驗(yàn)證的實(shí)現(xiàn)

    本篇文章介紹了,基于C#后臺(tái)調(diào)用跨域MVC服務(wù)及帶Cookie驗(yàn)證的實(shí)現(xiàn)。需要的朋友參考下
    2013-04-04
  • 淺析C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式

    淺析C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式

    本篇文章是對(duì)C#中數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例

    C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例

    本文主要介紹了C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • c#?chart縮放,局部放大問(wèn)題

    c#?chart縮放,局部放大問(wèn)題

    這篇文章主要介紹了c#?chart縮放,局部放大問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • WPF快速入門(mén)教程之綁定Binding

    WPF快速入門(mén)教程之綁定Binding

    初學(xué)wpf,經(jīng)常被Binding搞暈,以下記錄寫(xiě)B(tài)inding的基礎(chǔ)。下面這篇文章主要給大家介紹了關(guān)于WPF快速入門(mén)教程之綁定Binding的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-10-10
  • C#使用StreamReader和StreamWriter類(lèi)讀寫(xiě)操作文件

    C#使用StreamReader和StreamWriter類(lèi)讀寫(xiě)操作文件

    這篇文章介紹了C#使用StreamReader和StreamWriter類(lèi)讀寫(xiě)操作文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評(píng)論