淺談C#數(shù)組(一)
前言:
如果需要使用同一類型的多個對象,可以使用數(shù)組和集合。C#用特殊的記號聲明,初始化和使用數(shù)組。Array類在后臺發(fā)揮作用,它為數(shù)組中的元素排序和過濾提供了多個方法。使用枚舉器,可以迭代數(shù)組中的所有元素。
如果需要使用不同類型的多個對象,可以使用Tuple
(元組)類型。
一.簡單數(shù)組之一維數(shù)組
數(shù)組是一種數(shù)據(jù)結構,它可以包含同一個類型的多個元素。
1.數(shù)組的聲明
在聲明數(shù)組時,先定義數(shù)組中的元素類型,其后是一對空方括號和一個變量名。
int[] myArray;
2.數(shù)組的初始化
聲明了數(shù)組之后,就必須為數(shù)組分配內(nèi)存,以保存數(shù)組的所有元素。數(shù)組是引用類型,所以必須給它分配堆上的內(nèi)存。為此,應使用new運算符,指定數(shù)組中元素的類型和數(shù)量來初始化數(shù)組的變量。
myArray = new int[4];
在聲明和初始化數(shù)組后,變量myArray
就引用了4個整數(shù)值,它們位于托管堆上:
在指定了數(shù)組的大小后,就不能重新設置數(shù)組的大小。如果事先不知道數(shù)組中應包含多少個元素,就可以使用集合。
除了在兩個語句中聲明和初始化數(shù)組之外,還可以在一個語句中聲明和初始化數(shù)組:
int[] myArray = new int[4];
還可以使用數(shù)組初始化器為數(shù)組的每個元素復制。數(shù)組初始化器只能在聲明數(shù)組變量時使用,不能在聲明數(shù)組之后使用。
int[] myArray = new int[4]{1,3,5,7};
如果用花括號初始化數(shù)組,可以不指定數(shù)組的大小,因為編譯器會自動統(tǒng)計元素的個數(shù):
int[] myArray = new int[]{1,3,5,7};
也可以使用更簡單的形式:
int[] myArray = {1,3,5,7};
3.訪問數(shù)組元素
在聲明和初始化數(shù)組之后,就可以使用索引器訪問其中的元素了。數(shù)組只支持有整型參數(shù)的索引器。
索引器總是以0開頭,表示第一個元素。可以傳遞給索引器的最大值是元素個數(shù)減1,因為索引從0開始:
int[] myArray = {1,3,5,7}; int v1 = myArray[0]; int v2 = myArray[1]; myArray[3] = 4;
可以使用數(shù)組的Length
屬性獲取元素的個數(shù)。
4.數(shù)組中使用引用類型
數(shù)組除了能聲明預定義類型的數(shù)組,還可以聲明自定義類型的數(shù)組。
public class Person { public string FirstName { get; set; } public string LastName { get; set; } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } } Person[] myPersons = new Person[2]; myPersons[0] = new Person { FirstName = "Ayrton", LastName = "Senna" }; myPersons[1] = new Person { FirstName = "Michael", LastName = "Schumacher" };
如果數(shù)組中的元素是引用類型,就必須為每個數(shù)組元素分配內(nèi)存。如果使用了數(shù)組中未分配內(nèi)存的元素,就會拋出NullReferenceException
類型的異常。
下面是內(nèi)存情況:
對自定義類型也可以使用數(shù)組初始化器:
Person[] myPersons2 = { new Person { FirstName="Ayrton", LastName="Senna"}, new Person { FirstName="Michael", LastName="Schumacher"} };
二.多維數(shù)組
多維數(shù)組用兩個或多個整數(shù)來索引。
在C#中聲明多維數(shù)組,需要在方括號中加上逗號。數(shù)組在初始化時應指定每一維的大?。ㄒ卜Q為階)。
int[,] twoDim = new int[3,3]; twoDim[0,0] = 1; twoDim[0,1] = 2; twoDim[0,2] = 3; twoDim[1,0] = 4; twoDim[1,1] = 5; twoDim[1,2] = 6; twoDim[2,0] = 7; twoDim[2,1] = 8; twoDim[2,2] = 9;
聲明數(shù)組之后,就不能修改其階數(shù)了。
也可以使用初始化器來初始化多維數(shù)組:
int[,] twoDim ={ {1,2,3}, {4,5,6}, {7,8,9} };
使用數(shù)組初始化器時,必須初始化數(shù)組的每個元素,不能遺漏任何元素。
聲明一個三位數(shù)組:
int[,,] threeDim ={ {{1,2},{3,4}}, {{5,6},{7,8}}, {{9,10},{11,12}} }; Console.WriteLine(threeDim[0,1,1]);
三.鋸齒數(shù)組
二維數(shù)組的大小對應于一個矩形,而鋸齒數(shù)組的大小設置比較靈活,在鋸齒數(shù)組中,每一行都可以有不同的大小。
在聲明鋸齒數(shù)組時,要依次放置左右括號。在初始化鋸齒數(shù)組時,只在第一對方括號中設置該數(shù)組包含的行數(shù)。定義各行中元素個數(shù)的第二個方括號設置為空,因為這類數(shù)組的每一行包含不同的元素個數(shù)。之后,為每一行指定行中的元素個數(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};
迭代鋸齒數(shù)組中的所有元素的代碼可以放在嵌套的for循環(huán)中。在外層的for循環(huán)中迭代每一行,在內(nèi)層的for循環(huán)中迭代一行中的每個元素:
for(int row = 0;row<jagged.Length;row++) { for(int element = 0;element<jagged[row].Length;element++) { Console.WriteLine("row:{0}, element:{1},value:{2}",row,element,jagged[row][element]); } }
四.Array類
用方括號聲明數(shù)組是C#中使用Array
類的表示法。在后臺使用C#語法,會創(chuàng)建一個派生自抽象基類Array的新類。這樣,就可以使用Array類為每個C#數(shù)組定義的方法和屬性了。
Array類實現(xiàn)的其它屬性有LongLength
和Rank
。如果數(shù)組包含的元素個數(shù)超出了整數(shù)的取值范圍,就可以使用LongLength
屬性來獲得元素個數(shù)。使用Rank屬性可以獲得數(shù)組的維數(shù)。
1.創(chuàng)建數(shù)組
Array類是一個抽象類,所以不能使用構造函數(shù)來創(chuàng)建數(shù)組。但除了使用C#語法創(chuàng)建數(shù)組實例之外,還可以使用靜態(tài)方法CreateInstance()
創(chuàng)建數(shù)組。如果事先不知道元素的類型,該靜態(tài)方法就很有用,因為類型可以作為Type
對象傳遞給CreateInstance()
方法。
CreateInstance()
方法的第一個參數(shù)是元素的類型,第二個參數(shù)定義數(shù)組的大小。
可以使用SetValue()
方法設置對應元素的值,用GetValue()
方法讀取對應元素的值。
Array intArray1 = Array.CreateInstance(typeof(int), 5); for (int i = 0; i < 5; i++) { intArray1.SetValue(33, i); } for (int i = 0; i < 5; i++) { Console.WriteLine(intArray1.GetValue(i)); }
還可以將已經(jīng)創(chuàng)建的數(shù)組強制轉換稱聲明為int[]的數(shù)組:
int[] intArray2 = (int[])intArray1;
CreateInstance()
方法有許多重載版本,可以創(chuàng)建多維數(shù)組和索引不基于0的數(shù)組。
//創(chuàng)建一個2X3的二維數(shù)組,第一維基于1,第二維基于10: int[] lengths = { 2, 3 }; int[] lowerBounds = { 1, 10 }; Array racers = Array.CreateInstance(typeof(Person), lengths, lowerBounds); racers.SetValue(new Person { FirstName = "Alain", LastName = "Prost" }, index1: 1, index2: 10); racers.SetValue(new Person { FirstName = "Emerson", LastName = "Fittipaldi" }, 1, 11); racers.SetValue(new Person { FirstName = "Ayrton", LastName = "Senna" }, 1, 12); racers.SetValue(new Person { FirstName = "Michael", LastName = "Schumacher" }, 2, 10); racers.SetValue(new Person { FirstName = "Fernando", LastName = "Alonso" }, 2, 11); racers.SetValue(new Person { FirstName = "Jenson", LastName = "Button" }, 2, 12); Person[,] racers2 = (Person[,])racers; Person first = racers2[1, 10]; Person last = racers2[2, 12];
2.復制數(shù)組
因為數(shù)組是引用類型,所以將一個數(shù)組變量賦予另一個數(shù)組變量,就會得到兩個引用同一數(shù)組的變量。
數(shù)組實現(xiàn)ICloneable
接口。這個接口定義的Clone()
方法會復制數(shù)組,創(chuàng)建數(shù)組的淺表副本。
如果數(shù)組的元素是值類型,Clone()
方法會復制所有值:
int[] a1 = {1,2}; int[] a2 = (int[])a1.Clone();
如果數(shù)組包含引用類型,只復制引用。
除了使用Clone()
方法之外,還可以使用Array.Copy()
方法創(chuàng)建淺表副本。
Person[] beatles = { new Person { FirstName="John", LastName="Lennon" }, new Person { FirstName="Paul", LastName="McCartney" } }; Person[] beatlesClone = (Person[])beatles.Clone(); Person[] beatlesClone2 = new Person[2]; Array.Copy(beatlesClone,beatlesClone2,2);//注意與Clone的語法區(qū)別,Copy需要傳遞階數(shù)相同的已有數(shù)組。(還可以使用CopyTo()方法)
3.排序
Array類使用快速排序算法對數(shù)組中的元素進行排序。Sort()
方法需要數(shù)組中的元素實現(xiàn)IComparable
接口。因為簡單類型(如String,Int32)實現(xiàn)IComparable
接口,所以可以對包含這些類型的元素排序。
string[] names = { "Christina Aguilera", "Shakira", "Beyonce", "Gwen Stefani" }; Array.Sort(names); foreach (string name in names) { Console.WriteLine(name); }
如果對數(shù)組使用使用自定義類,就必須實現(xiàn)IComparable
接口。這個接口只定義了一個方法CompareTo()
方法,如果要比較的對象相等,該方法就返回0.如果該實例應排在參數(shù)對象的前面,該方法就返回小于i0de值。如果該實例應排在參數(shù)對象的后面,該方法就返回大于0的值。
public class Person : IComparable<Person> { public string FirstName { get; set; } public string LastName { get; set; } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } public int CompareTo(Person other) { if (other == null) throw new ArgumentNullException("other"); int result = this.LastName.CompareTo(other.LastName); if (result == 0) { result = this.FirstName.CompareTo(other.FirstName); } return result; } }
客戶端代碼:
Person[] persons = { new Person { FirstName="Damon", LastName="Hill" }, new Person { FirstName="Niki", LastName="Lauda" }, new Person { FirstName="Ayrton", LastName="Senna" }, new Person { FirstName="Graham", LastName="Hill" } }; Array.Sort(persons); foreach (Person p in persons) { Console.WriteLine(p); }
如果Person
對象的排序方式與上述不同,或者不能修改在數(shù)組中用作元素的類,就可以實現(xiàn)IComparer
接口或IComparer<T>
接口。這兩個接口定義了方法Compare()
方法。機型比較的類必須實現(xiàn)這兩個接口之一。
public enum PersonCompareType { FirstName, LastName } //通過使用實現(xiàn)了IComparer<T> 泛型接口的PersonComparer類比較Person對象數(shù)組。 public class PersonComparer : IComparer<Person> { private PersonCompareType compareType; public PersonComparer(PersonCompareType compareType) { this.compareType = compareType; } #region IComparer<Person> Members public int Compare(Person x, Person y) { if (x == null) throw new ArgumentNullException("x"); if (y == null) throw new ArgumentNullException("y"); switch (compareType) { case PersonCompareType.FirstName: return x.FirstName.CompareTo(y.FirstName); case PersonCompareType.LastName: return x.LastName.CompareTo(y.LastName); default: throw new ArgumentException( "unexpected compare type"); } } #endregion }
客戶端代碼:
Person[] persons = { new Person { FirstName="Damon", LastName="Hill" }, new Person { FirstName="Niki", LastName="Lauda" }, new Person { FirstName="Ayrton", LastName="Senna" }, new Person { FirstName="Graham", LastName="Hill" } }; Array.Sort(persons, new PersonComparer(PersonCompareType.FirstName)); foreach (Person p in persons) { Console.WriteLine(p); }
五.數(shù)組作為參數(shù)
數(shù)組可以作為參數(shù)傳遞給方法,也可以從方法中返回。
1.數(shù)組協(xié)變
數(shù)組支持協(xié)變。這表示數(shù)組可以聲明為基類,其派生類型的元素可以賦值于數(shù)組元素。
static void DisPlay(object[] o) { //.. }
可以給該方法傳遞一個Person[]
。
數(shù)組協(xié)變只能用于引用類型,不能用于值類型。
2.ArraySegment<T>
結構ArraySegment<T>
表示數(shù)組的一段。如果需要使用不同的方法處理某個大型數(shù)組的不同部分,那么可以把相應的數(shù)組部分復制到各個方法。
ArraySegment<T>結構包含了關于數(shù)組段的信息(偏移量和元素個數(shù))。
static void Main() { int[] ar1 = { 1, 4, 5, 11, 13, 18 }; int[] ar2 = { 3, 4, 5, 18, 21, 27, 33 }; var segments = new ArraySegment<int>[2] { new ArraySegment<int>(ar1, 0, 3), new ArraySegment<int>(ar2, 3, 3) }; var sum = SumOfSegments(segments); Console.WriteLine("sum of all segments: {0}", sum); } static int SumOfSegments(ArraySegment<int>[] segments) { int sum = 0; foreach (var segment in segments) { for (int i = segment.Offset; i < segment.Offset + segment.Count; i++) { sum += segment.Array[i]; } } return sum; }
數(shù)組段不復制原數(shù)組的元素,但原數(shù)組可以通過ArraySegment<T>
訪問。如果數(shù)組段中的元素改變了,這些變化就會反映到原數(shù)組中。
到此這篇關于淺談C#數(shù)組的文章就介紹到這了,更多相關C#數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
- 其實/FileShare就是控制文件流的“訪問權限”,當然,這僅僅是入門的文件操作,自己做了筆記,也希望能給大家?guī)韼椭?/div> 2014-01-01
C#結合數(shù)據(jù)庫實現(xiàn)驗證識別ID卡內(nèi)容的方法
這篇文章主要介紹了C#結合數(shù)據(jù)庫實現(xiàn)驗證識別ID卡內(nèi)容的方法,非常實用的功能,需要的朋友可以參考下2014-07-07C#實現(xiàn)HTML轉WORD及WORD轉PDF的方法
這篇文章主要介紹了C#實現(xiàn)HTML轉WORD及WORD轉PDF的方法,涉及C#實現(xiàn)HTML、WORD及PDF等文件格式轉換的相關技巧,需要的朋友可以參考下2015-09-09C#/VB.NET實現(xiàn)PPT或PPTX轉換為圖像功能
由于大多數(shù)便攜式設備支持瀏覽圖片而不支持瀏覽PowerPoint 文件,所以相比較而言,圖像對于用戶而言更加友好。本文將利用C#/VB.NET實現(xiàn)PPT或PPTX轉換為圖像功能,需要的可以參考一下2022-08-08C#中Hashtable和Dictionary的區(qū)別與用法示例
由于 Hashtable 和 Dictionary 同時存在, 在使用場景上必然存在選擇性, 并不任何時刻都能相互替代。所以這篇文章主要給大家介紹了關于C#中Hashtable和Dictionary區(qū)別的相關資料,需要的朋友可以參考下2021-05-05最新評論