<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      前言

        如果需要使用相同的類型的多個(gè)對(duì)象,就可以使用集合和數(shù)組,這一節(jié)主要講解數(shù)組,其中會(huì)重點(diǎn)涉及到Span<T>結(jié)構(gòu)和ArrayPool數(shù)組池。我們也會(huì)先涉及到
      簡(jiǎn)單的數(shù)組、多維數(shù)組、鋸齒數(shù)組、Array類。

      簡(jiǎn)單的數(shù)組、多維數(shù)組、鋸齒數(shù)組

        簡(jiǎn)單的數(shù)組介紹

        數(shù)組的聲明:
      Int [] myArray;
        初始化:
      myArray=new int[4];
        還可以:
      Int [] myArray=new int []{1,2,3,4};
        訪問(wèn)數(shù)組:
      myArray[0];
      ?

        多維數(shù)組介紹

        一般的數(shù)組(也稱一維數(shù)組)是用一個(gè)數(shù)字來(lái)索引,多維數(shù)組用兩個(gè)或兩個(gè)以上的數(shù)字進(jìn)行索引。

        聲明多維數(shù)組時(shí)中間以,隔開(kāi),我們下面聲明一個(gè)二維數(shù)組。
      int [,] twodim=new int [3,3] int[,] twodim = { { 1,2,3}, { 4,5,6}, { 7,8,9} };
      ?

        一個(gè)三維數(shù)組。
      int[,,] threedim = { { { 1,2},{ 3,4} }, {{ 5,6},{ 7,8} }, { { 9,10},{ 11,12} }
      }; Console.WriteLine(threedim[0,1,1]);
      ?

        鋸齒數(shù)組

        二維數(shù)組圖形:


      1

      2

      3


      4

      5

      6


      7

      8

      9

      ?

        

      ?

      ?

      ?

        鋸齒數(shù)組



      1

      2


      3

      4

      5

      6


      7

      8

      9

      ?

      ?

      ?

      ?

      ?


        在聲明鋸齒數(shù)組的時(shí)候要依次放置左右括號(hào)。在初始化鋸齒數(shù)組時(shí),只對(duì)第一對(duì)方括號(hào)中設(shè)置該數(shù)組包含的行數(shù),定義各行中元素個(gè)數(shù)的第二個(gè)方括號(hào)設(shè)為空,因?yàn)檫@類數(shù)組的每一行包含不同的元素個(gè)數(shù)。
         int[][] jagged = new int[3][]; jagged[0] = new int[2] { 1, 2 }; jagged[1] =
      new int[4] { 3, 4, 5, 6 }; jagged[2] = new int[3] { 7, 8, 9 };
      ?

      Array類

        創(chuàng)建數(shù)組:
      Array intArray1 = Array.CreateInstance(typeof(int), 5); for (int i = 0; i <
      intArray1.Length; i++) { intArray1.SetValue(33, i);   }
        上面這段代碼,描述了Array數(shù)組的創(chuàng)建以及設(shè)置值。CreateInstance()方法第一個(gè)參數(shù)為元素的類型,第二個(gè)參數(shù)為定義數(shù)組的大小。
      SetValue()方法設(shè)置值第一個(gè)參數(shù)為設(shè)置IDE值,第二個(gè)參數(shù)為設(shè)置的索引。

        復(fù)制數(shù)組:
      int[] intArray1 = { 1,2}; int[] intArray2 = (int[])intArray1.Clone();
        因?yàn)閿?shù)組是引用類型的,所以將一個(gè)數(shù)組的變量賦予另一個(gè)數(shù)組變量,就會(huì)得到兩個(gè)引用同一個(gè)數(shù)組的變量,這是使用的是Clone()方法創(chuàng)建數(shù)組的淺表副本。使用
      Copy()方法也可以創(chuàng)建淺表副本,Clone()方法會(huì)創(chuàng)建一個(gè)數(shù)組,而Copy()方法必須傳遞階數(shù)相同且有足夠元素的已有數(shù)組。

        排序:
      class Program { static void Main(string[] args) { int[] list = { 34, 72, 13, 44
      ,25, 30, 10 }; Console.Write("原始數(shù)組: "); foreach (int i in list) {
      Console.Write(i+ " "); } Console.WriteLine(); // 逆轉(zhuǎn)數(shù)組 Array.Reverse(list);
      Console.Write("逆轉(zhuǎn)數(shù)組: "); foreach (int i in list) { Console.Write(i + " "); }
      Console.WriteLine();// 排序數(shù)組 Array.Sort(list); Console.Write("排序數(shù)組: "); foreach
      (int i in list) { Console.Write(i + " "); } Console.WriteLine(); } }
      ?

        輸出:
      原始數(shù)組: 34 72 13 44 25 30 10 逆轉(zhuǎn)數(shù)組: 10 30 25 44 13 72 34 排序數(shù)組: 10 13 25 30 34 44
      72
        在上述方法中Array.Sort()方法實(shí)現(xiàn)了數(shù)組的排序,而Array.Reverse()實(shí)現(xiàn)了數(shù)組的逆轉(zhuǎn) 。

      ArrayPool數(shù)組池


        接下來(lái)重點(diǎn)來(lái)了,本文的重點(diǎn)一,ArrayPool數(shù)組池。如果一個(gè)應(yīng)用需要?jiǎng)?chuàng)建和銷毀許多的數(shù)組,垃圾收集器就要花費(fèi)很多的功夫來(lái)做這些工作,為了較少垃圾收集器的工作,這里我們可以使用ArrayPool類來(lái)使用數(shù)組池。ArrayPool管理一個(gè)數(shù)組池,數(shù)組可以再這里租借內(nèi)存,并且返回到這里。需要引用
      using?System.Buffers;

        創(chuàng)建數(shù)組池:

      ArrayPool<int> arrayPool = ArrayPool<int>.Create(maxArrayLength:40000,
      maxArraysPerBucket:10);
        maxArrayLength的默認(rèn)值是1024*10224字節(jié)(數(shù)組的長(zhǎng)度),maxArraysPerBucket默認(rèn)值是50(數(shù)組的數(shù)量)。

        這里還可以使用以下方法來(lái)使用預(yù)定義的共享池。
      ArrayPool<int> sharePool = ArrayPool<int>.Shared;
        下面我們就一起看看如何去使用這個(gè)數(shù)組池吧:

      ?
      class Program { static void Main(string[] args) { //定義數(shù)組池 ArrayPool<int>
      arrayPool = ArrayPool<int>.Create(maxArrayLength: 10000, maxArraysPerBucket: 10
      );//定義使用數(shù)組的長(zhǎng)度 int arrayLenght = 5; int[] array = arrayPool.Rent(arrayLenght); //
      輸出數(shù)組的長(zhǎng)度 Console.WriteLine($"定義數(shù)組長(zhǎng)度:{arrayLenght},實(shí)際數(shù)組長(zhǎng)度:{array.Length}"); //
      對(duì)數(shù)組進(jìn)行賦值 array[0] = 0; array[1] = 1; array[2] = 2; array[3] = 3; array[4] = 4; //
      輸出數(shù)組的值 foreach (var item in array) { Console.WriteLine(item); } //
      將內(nèi)存返回給數(shù)組池,clearArray設(shè)置True清除數(shù)組,下次調(diào)用時(shí)為空,設(shè)置False,保留數(shù)組,下次調(diào)用還是現(xiàn)在的值
      arrayPool.Return(array, clearArray:true); foreach (var item in array) {
      Console.WriteLine(item); } } }
      ?

        在上面事例中,
      我們使用Rent()方法請(qǐng)求池中的內(nèi)存,Rent方法返回一個(gè)數(shù)組,其中至少包含所請(qǐng)求的元素個(gè)數(shù)。返回的數(shù)組可能會(huì)用到更多的內(nèi)存,池中最少的請(qǐng)求為16個(gè)元素,緊接著是32,64,128以此類推。所以在上述例子中我們請(qǐng)求的長(zhǎng)度為5,但是實(shí)際使用的元素個(gè)數(shù)為16個(gè),多余的將根據(jù)類型對(duì)其賦值0或者null。


        我們使用Return()方法將數(shù)組返回到池中,這里使用了一個(gè)可選參數(shù)clearArray,指定是否清除該數(shù)組,不清除的話下一個(gè)從池中租用這個(gè)數(shù)組的人可以讀取到其中的數(shù)據(jù)。清除數(shù)據(jù)可以避免這種情況,但是會(huì)消耗更多的CPU時(shí)間。

      Span<T>

        Span<T>介紹


        為了快速訪問(wèn)托管或非托管的連續(xù)內(nèi)存,可以使用Spam<T>結(jié)構(gòu)。一個(gè)可以使用Span<T>結(jié)構(gòu)的例子就是數(shù)組,Span<T>結(jié)構(gòu)在后臺(tái)保存在連續(xù)的內(nèi)存中,另一個(gè)例子就是長(zhǎng)字符串。

        使用Span<T>結(jié)構(gòu),可以直接訪問(wèn)數(shù)組元素。數(shù)組的元素沒(méi)有復(fù)制,但是它們可以直接調(diào)用,并且比復(fù)制還快。
      class Program { static void Main(string[] args) { int[] arr1 = { 3, 5, 7, 9, 11
      ,13, 15, 18, 19 }; var span1 = new Span<int>(arr1); span1[1] = 11;
      Console.WriteLine(arr1[1]); } }
        輸出:

      ?

      ?


        這里將創(chuàng)建的arr1數(shù)組傳遞給Span<T>,同時(shí)Span<T>類型提供了一個(gè)索引器,這里直接修改span1的第二個(gè)值,然后再輸出arr1數(shù)組中的第二個(gè)值,也是被其修改過(guò)得值。

        Span<T>切片


        Span<T>它一個(gè)強(qiáng)大的特性是,可以使用它訪問(wèn)數(shù)組的部分或者切片,使用切片的時(shí)候不會(huì)復(fù)制數(shù)組元素,他們是從Span中直接訪問(wèn)的。下面代碼介紹了創(chuàng)建切片的兩種方法:
      class Program { static void Main(string[] args) { //定義簡(jiǎn)單的數(shù)組 int[] arr2 = { 3, 5
      ,7, 9, 11, 13, 15, 18, 19, 20, 30, 40, 50, 60 }; //
      Span<T>對(duì)數(shù)組進(jìn)行切片,訪問(wèn)arr2數(shù)組,從第三個(gè)開(kāi)始,取長(zhǎng)度6個(gè)的一個(gè)數(shù)組。 var span3 = new Span<int>(arr2,
      start:3, length: 6); //輸出切片中的值 foreach (var item in span3) {
      Console.WriteLine(item); } Console.WriteLine(""); Console.WriteLine("");
      Console.WriteLine(""); //對(duì)span3進(jìn)行切片處理,從第二個(gè)開(kāi)始,去長(zhǎng)度4個(gè)的一個(gè)數(shù)組 var span4 =
      span3.Slice(start:2, length: 4); foreach (var item in span4) {
      Console.WriteLine(item); } } }
      ?

        輸出:

      ?

      ?

        使用Span<T>改變值

        前面介紹了如何使用Span<T>的索引器,更改數(shù)組的元素,下面介紹的將會(huì)有更多的選項(xiàng),關(guān)于修改元素的值及復(fù)制。
      class Program { static void Main(string[] args) { //定義簡(jiǎn)單的數(shù)組 int[] arr = { 3, 5,
      7, 9, 11, 13, 15, 18, 19, 20, 30, 40, 50, 60 }; //將數(shù)組傳遞給span var span = new
      Span<int>(arr); var span2 = new Span<int>(arr); //對(duì)span進(jìn)行切片處理,從第四個(gè)開(kāi)始 var span3
      = span.Slice(start:4 ); //調(diào)用clear方法,用0填充span3 span3.Clear(); foreach (var item
      in span3) { Console.WriteLine("span3的值:"+item); } Console.WriteLine("span3的長(zhǎng)度:"+
      span3.Length);//創(chuàng)建新的切片span4,從span2開(kāi)始,長(zhǎng)度3 Span<int> span4 = span2.Slice(start: 3
      , length:3); //調(diào)用Fill方法,用傳入的值填充span4 span4.Fill(42); foreach (var item in
      span4) { Console.WriteLine("span4的值"+item); } Console.WriteLine("span4的長(zhǎng)度"+
      span4.Length);//將span4復(fù)制給span,復(fù)制失敗 span4.CopyTo(span); //將span復(fù)制給span3 復(fù)制失敗 if
      (!span.TryCopyTo(span3)) { Console.WriteLine("復(fù)制不了"); } } }
      ?

        輸出:

      ?

      ?

        上面事例中,
      顯示調(diào)用clear()方法,該方法用0填充Span,然后調(diào)用了Fill()方法,該方法用傳遞給Fill方法的值來(lái)填充Span,同時(shí)也可以將一個(gè)Span<T>復(fù)制給另一個(gè)Span<T>,這里先是采用的CopyTo,在這個(gè)方法中,如果另一個(gè)目標(biāo)span不夠大,就會(huì)復(fù)制失敗,這里可以使用TryCopyTo來(lái)優(yōu)化此功能,如果目標(biāo)不夠大,將會(huì)返回false。以此來(lái)判斷是否復(fù)制成功。上面例子中span4長(zhǎng)度為3,而span長(zhǎng)度為14,這里是復(fù)制成功了,然后其下面的操作,因?yàn)閟pan3的長(zhǎng)度是10,span復(fù)制給span3失敗了。因?yàn)閟pan3不夠大。


        上面事例中提供了改變值的一些方法,當(dāng)我們不需要對(duì)值進(jìn)行改變,只需要對(duì)數(shù)組進(jìn)行讀訪問(wèn)的時(shí)候,我們可以使用ReadOnlySpan<T>。這里定義了只讀的Span
      ReadOnlySpan<int> readonlySpan = new ReadOnlySpan<int>(arr);
      ?

      總結(jié)


        在本篇文章中,重點(diǎn)介紹了ArrayPool數(shù)組池和Span<T>結(jié)構(gòu),通過(guò)使用數(shù)組池,來(lái)降低數(shù)組創(chuàng)建和銷毀時(shí)消耗的性能,減少垃圾回收器的工作,使用Span<T>可以快速的訪問(wèn)托管及非托管代碼,創(chuàng)建切片來(lái)對(duì)數(shù)組和長(zhǎng)字符串進(jìn)行一定的操作。更加高效的操作數(shù)組。

      ?

        青少年是一個(gè)美好而又是一去不可再得的時(shí)期,是將來(lái)一切光明和幸福的開(kāi)端。——加里寧


        我的博客即將同步至騰訊云+社區(qū),邀請(qǐng)大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=2n1gp5jweqww4

      ?

      ?

      ?

                            c#基礎(chǔ)知識(shí)詳解系列
      <https://www.cnblogs.com/hulizhong/p/11205119.html>

      ?

        歡迎大家掃描下方二維碼,和我一起學(xué)習(xí)更多的C#知識(shí)

      ?

      ?

      ?

        

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          《有夫之妇的精油按摩》 | 色噜噜狠狠色综合网图区 | 亚洲免费高清视频 | 美女操软件 | www.人人cao | 国产精品国产伦子伦露看 | 欧美男人私gay网站 | 日韩国产片 | 做爱视频成人的 | 韩国无码内射 |