第十四章 數(shù)組.
內(nèi)容摘要:
 本章討論了數(shù)組的方方面面,對于這種常用類型進(jìn)行深入研究。
 
一、 數(shù)組簡介
 三種類型:一維數(shù)組、多維數(shù)組、交錯數(shù)組(jagged aray)
l 一維數(shù)組:
 int32[] myintegers;
 myintegers = new int32[100];
l 多維數(shù)組:
int32[,] myintegers;
 myintegers = new int32[100,100];
l 交錯數(shù)組:交錯數(shù)組不受cls支持
 point[][] mypolygons = new point[3][];
 mypolygons[0] = new point[10];
 mypolygons[1] = new point[20];
 mypolygons[2] = new point[30];
二、 system.array
 請參考.net framework sdk中相關(guān)描述
三、 數(shù)組轉(zhuǎn)型
l 兩數(shù)組必須有同樣的維數(shù)
l 兩數(shù)組中元素類型間存在隱式或顯式轉(zhuǎn)換
l 除使用array.copy()方法外,不允許將值類型數(shù)組轉(zhuǎn)換為其他類型數(shù)組(array.copy方法會根據(jù)需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換或裝箱操作)
array.copy()方法能夠執(zhí)行的類型轉(zhuǎn)換如下:
l 將值類型轉(zhuǎn)換為引用類型,將int32轉(zhuǎn)換為object
l 將引用類型轉(zhuǎn)換為值類型,將object轉(zhuǎn)換為int32
l 拓寬(widen)clr基類型,如將int32轉(zhuǎn)換為double
 
下面這個示例提供了一個反面教材(切勿效仿,后果自負(fù)?。┝酥殿愋偷难b換:
using system;
//自定義一個值類型,該類型可以與int32進(jìn)行互轉(zhuǎn)換
struct myage
{
 private int32 m_nage; 
 
 public myage(int32 nage)
 {
 this.m_nage = nage; 
 }
 
 //轉(zhuǎn)換操作符
 public static implicit operator myage(int32 nage)
 {
 return new myage(nage); 
 }
 
 public static explicit operator int32(myage age)
 {
 return age.toint32(); 
 }
 
 public int32 toint32()
 {
 return m_nage; 
 }
 
 public override string tostring()
 {
 return "age : " + m_nage;
 }
}
 
public class arraytest
{
 public static void main()
 {
 int32[] arrint = new int32[10];
 for(int i = 0; i < arrint.length; i ++)
 {
 arrint[i] = i; 
 } 
 
 myage[] arrage = new myage[arrint.length];
 array.copy(arrint, arrage, arrint.length);
 
 foreach(myage age in arrage)
 {
 console.writeline(age.tostring()); 
 }
 } 
}
 
/*運(yùn)行結(jié)果
未處理的異常: system.arraytypemismatchexception: 不能將源數(shù)組類型分配給目標(biāo)數(shù)組
類型。
 at system.array.copy(array sourcearray, int32 sourceindex, array destinationa
rray, int32 destinationindex, int32 length)
 at system.array.copy(array sourcearray, array destinationarray, int32 length)
 
 at arraytest.main()
 
*/
注:1、上述代碼是不能運(yùn)行的。雖然為值類型定義了轉(zhuǎn)換操作,但仍不滿足上述轉(zhuǎn)換條件,可見自定義的轉(zhuǎn)換操作不被array.copy()認(rèn)可。
 2、上述代碼中涉及到類型轉(zhuǎn)換操作符的應(yīng)用,請參考讀書筆記第九章 方法
四、 數(shù)組傳遞與返回
 注意事項(xiàng):
l 為獲得對數(shù)組元素的深拷貝,要求每個元素都實(shí)現(xiàn)icloneable接口。需要注意的是應(yīng)在適當(dāng)時候使用深拷貝操作(詳情請參見《c# primer》p185)
l 返回數(shù)組引用的方法若不含數(shù)組元素應(yīng)該返回一個包含0個元素的數(shù)組而不是null
l 不在方法中返回類型內(nèi)部的數(shù)組引用,而是重新構(gòu)造一個深拷貝的數(shù)組返回。
五、 創(chuàng)建下限非0的數(shù)組
 使用array.createinstance()方法:
 public static array createinstance(type elementtype, int[] lengths, int[] lowerbounds);
 elementtype : 要創(chuàng)建的 array 的 type。
 lengths : 一維數(shù)組,它包含要創(chuàng)建的 array 的每個維度的大小
 lowerbounds : 一維數(shù)組,它包含要創(chuàng)建的 array 的每個維度的下限(起始索引)。 
 
六、 快速數(shù)組訪問
要點(diǎn):
l 使用非安全的代碼
l 使用指針訪問數(shù)組
l 可進(jìn)行非安全數(shù)組操作的元素為數(shù)值基元類型、boolean、枚舉類型或字段為上述類型的結(jié)構(gòu)類型,或字段為上述結(jié)構(gòu)類型的結(jié)構(gòu)類型……(遞歸定義的結(jié)構(gòu)類型)
如下面例程所示:
using system;
 
public class arrsafe
{
 unsafe public static void main() //此處表明使用非安全代碼
 {
 int32[] arr = new int32[]{1,2,3,4,5};
 fixed(int32 *element = arr) //使用指針訪問
 {
 for(int32 i = 0; i < arr.length; i ++)
 {
 console.writeline(element[i]); 
 }
 }
 }
}
七、 重新調(diào)整數(shù)組的長度
l 使用如下方法獲取創(chuàng)建新的數(shù)組長度(請參見.net framework sdk中的詳細(xì)描述)
創(chuàng)建使用從零開始的索引、具有指定 type 和長度的一維 array。
[c#] public static array createinstance(type, int);
創(chuàng)建使用從零開始的索引、具有指定 type 和維長的多維 array。維的長度在一個 32 位整數(shù)數(shù)組中指定。
[c#] public static array createinstance(type, params int[]);
創(chuàng)建使用從零開始的索引、具有指定 type 和維長的多維 array。維的長度在一個 64 位整數(shù)數(shù)組中指定。
[c#] public static array createinstance(type, params long[]);
創(chuàng)建使用從零開始的索引、具有指定 type 和維長的二維 array。
[c#] public static array createinstance(type, int, int);
創(chuàng)建具有指定下限、指定 type 和維長的多維 array。
[c#] public static array createinstance(type, int[], int[]);
創(chuàng)建使用從零開始的索引、具有指定 type 和維長的三維 array。
[c#] public static array createinstance(type, int, int, int);
 
l 然后使用array.copy()方法,將原來的數(shù)組拷貝到新數(shù)組中