在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);
}