在System名稱空間裡面有許多跟Array操作相關的類。其中 System.Array 類裡面就提供了以下常用的方法:
BinarySearch:使用二進位搜尋演算法在一維的排序 Array 中搜尋值。
Copy:將一個 Array 的一部分元素複製到另一個 Array 中,並根據需要執行類型強制轉換和裝箱。
CopyTo:將當前一維 Array 的所有元素複製到指定的一維 Array 中。
Resize:將數組的大小更改為指定的新大小。
Sort:對一維 Array 對象中的元素進行排序。
與大多數類不同,Array 提供 CreateInstance 方法,以便允許後期綁定訪問,而不是提供公用建構函式。Array.Copy 方法不僅可在同一類型的數組之間複製元素,而且可在不同類型的標準數組之間複製元素;它會自動處理強制類型轉換。有些方法,如 CreateInstance、Copy、CopyTo、GetValue 和 SetValue,提供重載(接受 64 位元整數作為參數),以適應大容量數組。LongLength 和 GetLongLength 返回指示數組長度的 64 位元整數。在執行需要對 Array 進行排序的操作(如 BinarySearch)之前,必須對 Array 進行排序。
ArrayList跟Array不同,前者是集合對象,ArrayList 的 ToArray 方法可以直接將ArrayList裡面的全部元素匯出到一個數組裡,而不需用迴圈逐個逐個元素地複製到一個數組。
ToArray的使用方法如下:
ArrayList ay = new ArrayList();
ay.Add("sheep");
ay.Add("cat");
ay.Add("dog");
string[] al= (string[])ay.ToArray(typeof(string));
Console.WriteLine(al[0]);
關鍵的地方在於 ToArray的參數,這裡應該用反射中的 typeof 擷取arraylist裡面元素的未經處理資料類型。
在數組中有一種比較特殊的:位元組數組,即 byte[]。記憶體、檔案中的資料都是以位元組數組的形式儲存的,如果程式需要對資料進行操作的話,或多或少都會使用到byte[]。
對於byte[]跟其他類型的相互轉換問題,在C++中,使用Memorycopy函數即可完成,雖然在C#裡面也有類似MemoryCopy的函數:Buffer.BlockCopy,但由於強型別的特性,在C#裡它並實現不了位元組數組跟其他類型轉換的功能。
為瞭解決這個問題,需要手工寫將其他類型的資料通過位元運算和邏輯運算而得到位元組數組。如下面的代碼:
//整型轉換為位元組數組
int i = 1234567; //對應的十六進位是:0012D687
byte[] db = new byte[4]; //int為4位元組(即32位)的整數
db[0] = (byte)(i & 0x000000ff); //取第1,2位
db[1] = (byte)((i & 0x0000ff00) >> 8); //取第3,4位,並右移2位
db[2] = (byte)((i & 0x00ff0000) >> 16); //取第5,6位,並右移4位
db[3] = (byte)((i & 0xff000000) >> 24); //取第7,8位,並右移6位
Console.WriteLine("使用 AND 位元運算和移位元運算 轉換成數組:{0},{1},{2},{3}", db[0], db[1], db[2], db[3]);
//位元組數群組轉換為整型
int j = 0;
j = (int)db[0]; //還原第1位元組(低位)
j += (int)db[1] << 8; //還原第2位元組
j += (int)db[2] << 16; //還原第3位元組
j += (int)db[3] << 24; //還原第4位元組(高位)
Console.WriteLine("使用移位元運算還原為整數:{0}", j);
另外一個方法是使用Marshal來實現,Marshal類包含了記憶體操作的大部分方法,如空間的分配,指標,記憶體複製,記憶體讀寫等。下面用Marshal實現上面同樣的功能的代碼:
int i = 1234567; //對應的十六進位是:0012D687
//使用Marshal轉換到數組
byte[] newdb = new byte[4];
IntPtr p=Marshal.AllocHGlobal(4); //分配記憶體空間,返回空間指標
Marshal.WriteInt32(p, i); //將int的值寫到該空間
Marshal.Copy(p, newdb, 0, 4); //將記憶體空間的內容複寫到位元組數組newdb,各參數的含義 source,destination,startindex,length
Console.WriteLine("使用Marshal轉換整數為數組:{0},{1},{2},{3}", newdb[0], newdb[1], newdb[2], newdb[3]);
//使用Marshal轉換到整數
p = Marshal.AllocHGlobal(4); //分配記憶體空間,返回空間指標
Marshal.Copy(newdb, 0, p, 4); //將db複製到記憶體,各參數的含義 source,startindex,destination,length
int k = Marshal.ReadInt32(p); //讀取記憶體到變數k
Console.WriteLine("使用Marshal從位元組數組還原整數{0}",k);
如果想簡單一點的話,也可以使用System.BitConverter類,下面是一些常用的方法:
GetBytes () 以位元組數組的形式返回其他資料類型的值。
ToBoolean 返回由位元組數組中指定位置的一個位元組轉換來的布爾值。
ToChar 返回由位元組數組中指定位置的兩個位元組轉換來的 Unicode 字元。
ToDouble 返回由位元組數組中指定位置的八個位元組轉換來的雙精確度浮點數。
ToInt16 返回由位元組數組中指定位置的兩個位元組轉換來的 16 位有符號整數。
ToInt32 返回由位元組數組中指定位置的四個位元組轉換來的 32 位有符號整數。
ToInt64 返回由位元組數組中指定位置的八個位元組轉換來的 64 位元有符號整數。
ToSingle 返回由位元組數組中指定位置的四個位元組轉換來的單精確度浮點數。
ToString 已重載。 返回由位元組數組的元素轉換來的 String。
***********************************************************************************************
//整數到位元組數組的轉換
public static byte[] intToByte(int number) {
int temp = number;
byte[] b=new byte[4];
for (int i=b.length-1;i>-1;i--){
b = new Integer(temp&0xff).byteValue(); //將最高位儲存在最低位
temp = temp >> 8; //向右移8位
}
return b;
}
//位元組數組到整數的轉換
public static int byteToInt(byte[] b) {
int s = 0;
for (int i = 0; i < 3; i++) {
if (b >= 0)
s = s + b;
else
s = s + 256 + b;
s = s * 256;
}
if (b[3] >= 0) //最後一個之所以不乘,是因為可能會溢出
s = s + b[3];
else
s = s + 256 + b[3];
return s;
}
//字元到位元組轉換
public static byte[] charToByte(char ch){
int temp=(int)ch;
byte[] b=new byte[2];
for (int i=b.length-1;i>-1;i--){
b = new Integer(temp&0xff).byteValue(); //將最高位儲存在最低位
temp = temp >> 8; //向右移8位
}
return b;
}
//位元組到字元轉換
public static char byteToChar(byte[] b){
int s=0;
if(b[0]>0)
s+=b[0];
else
s+=256+b[0];
s*=256;
if(b[1]>0)
s+=b[1];
else
s+=256+b[1];
char ch=(char)s;
return ch;
}
//浮點到位元組轉換
public static byte[] doubleToByte(double d){
byte[] b=new byte[8];
long l=Double.doubleToLongBits(d);
for(int i=0;i<b.length;i++){
b=new Long(l).byteValue();
l=l>>8;
}
return b;
}
//位元組到浮點轉換
public static double byteToDouble(byte[] b){
long l;
l=b[0];
l&=0xff;
l|=((long)b[1]<<8);
l&=0xffff;
l|=((long)b[2]<<16);
l&=0xffffff;
l|=((long)b[3]<<24);
l&=0xffffffffl;
l|=((long)b[4]<<32);
l&=0xffffffffffl;
l|=((long)b[5]<<40);
l&=0xffffffffffffl;
l|=((long)b[6]<<48);
l&=0xffffffffffffffl;
l|=((long)b[7]<<56);
return Double.longBitsToDouble(l);
}