C#中的类型转换

来源:本站整理  作者:不详
摘要:c#出来也有些日子了,最近由于编程的需要,对c#的类型转换做了一些研究,其内容涉及c#的装箱/拆箱/别名、数值类型间相互转换、字符的ascii码和unicode码、数值字符串和数值之间的转换、字符串和字符数组/字节数组之间的转换、各种数值类型和字节数组之间的转…

6. 字符串和字节数组之间的转换

如果还想从 system.string 类中找到方法进行字符串和字节数组之间的转换,恐怕你会失望了。为了进行这样的转换,我们不得不借助另一个类:system.text.encoding。该类提供了 bye[] getbytes(string) 方法将字符串转换成字节数组,还提供了 string getstring(byte[]) 方法将字节数组转换成字符串。

system.text.encoding 类似乎没有可用的构造函数,但我们可以找到几个默认的 encoding,即 encoding.default(获取系统的当前 ansi 代码页的编码)、encoding.ascii(获取 7 位 ascii 字符集的编码)、encoding.unicode(获取采用 little-endian 字节顺序的 unicode 格式的编码)、encoding.utf7(获取 utf-7 格式的编码)、encoding.utf8(获取 utf-8 格式的编码) 等。这里主要说说 encoding.default 和 encoding.unicode 用于转换的区别。

在字符串转换到字节数组的过程中,encoding.default 会将每个单字节字符,如半角英文,转换成 1 个字节,而把每个双字节字符,如汉字,转换成 2 个字节。而 encoding.unicode 则会将它们都转换成两个字节。我们可以通过下列简单的了解一下转换的方法,以及使用 encoding.default 和 encodeing.unicode 的区别:

private void teststringbytes() {
string s = "c#语言";
byte[] b1 = system.text.encoding.default.getbytes(s);
byte[] b2 = system.text.encoding.unicode.getbytes(s);
string t1 = "", t2 = "";
foreach (byte b in b1) {
t1 += b.tostring("") + " ";
}
foreach (byte b in b2) {
t2 += b.tostring("") + " ";
}
this.textbox1.text = "";
this.textbox1.appendtext("b1.length = " + b1.length + "\n");
this.textbox1.appendtext(t1 + "\n");
this.textbox1.appendtext("b2.length = " + b2.length + "\n");
this.textbox1.appendtext(t2 + "\n");
}

运行结果如下,不说详述,相信大家已经明白了。

b1.length = 6
67 35 211 239 209 212
b2.length = 8
67 0 35 0 237 139 0 138

将字节数组转换成字符串,使用 encoding 类的 string getstring(byte[]) 或 string getstring(byte[], int, int) 方法,具体使用何种 encoding 还是由编码决定。在 teststringbytes() 函数中添加如下语句作为实例:

byte[] bs = {97, 98, 99, 100, 101, 102};
string ss = system.text.encoding.ascii.getstring(bs);
this.textbox1.appendtext("the string is: " + ss + "\n");

运行结果为:the string is: abcdef

7. 各种数值类型和字节数组之间的转换

在第 1 条中我们可以查到各种数值型需要使用多少字节的空间来保存数据。将某种数值类型的数据转换成字节数组的时候,得到的一定是相应大小的字节数组;同样,需要把字节数组转换成数值类型,也需要这个字节数组大于相应数值类型的字节数。

现在介绍此类转换的主角:system.bitconverter。该类提供了 byte[] getbytes(...) 方法将各种数值类型转换成字节数组,也提供了 toint32、toint16、toint64、touint32、tosignle、toboolean 等方法将字节数组转换成相应的数值类型。

由于这类转换通常只是在需要进行较细微的编码/解码操作时才会用到,所以这里就不详细叙述了,仅把 system.bitconverter 类介绍给大家。

8. 转换成十六进制

任何数据在计算机内部都是以二进制保存的,所以进制与数据的存储无关,只与输入输出有关。所以,对于进制转换,我们只关心字符串中的结果。

在上面的第 4 条中提到了 tostring() 方法可以将数值转换成字符串,不过在字符串中,结果是以十进制显示的。现在我们带给它加一些参数,就可以将其转换成十六进制——使用 tostring(string) 方法。

这里需要一个 string 类型的参数,这就是格式说明符。十六进制的格式说明符是 "x" 或者 "x",使用这两种格式说明符的区别主要在于 a-f 六个数字:"x" 代表 a-f 使用小写字母表示,而 "x" 而表示 a-f 使用大字字母表示。如下例:

private void testhex() {
int a = 188;
this.textbox1.text = "";
this.textbox1.appendtext("a(10) = " + a.tostring() + "\n");
this.textbox1.appendtext("a(16) = " + a.tostring("x") + "\n");
this.textbox1.appendtext("a(16) = " + a.tostring("x") + "\n");
}

运行结果如下:

a(10) = 188
a(16) = bc
a(16) = bc

这时候,我们可能有另一种需求,即为了显示结果的整齐,我们需要控制十六进制表示的长度,如果长度不够,用前导的 0 填补。解决这个问题,我们只需要在格式说明符“x”或者“x”后写上表示长度的数字就行了。比如,要限制在 4 个字符的长度,可以写成“x4”。在上例中追加一句:

this.textbox1.appendtext("a(16) = " + a.tostring("x4") + "\n");

其结果将输出 a(16) = 00bc。

现在,我们还要说一说如何将一个表示十六进制数的字符串转换成整型。这一转换,同样需要借助于 parse() 方法。这里,我需要 parse(string, system.globalization.numberstyles) 方法。第一个参数是表示十六进制数的字符串,如“ab”、“20”(表示十进制的 32) 等。第二个参数 system.globalization.numberstyles 是一个枚举类型,用来表示十六进制的枚举值是 hexnumber。因此,如果我们要将“ab”转换成整型,就应该这样写:int b = int.parse("ab", system.globalization.numberstyles.hexnumber),最后得到的 b 的值是 171。

9. 日期型数据和长整型数据之间的转换

为什么要将日期型数据转换为长整型数据呢?原因很多,但就我个人来说,经常将它用于数据库的日期存储。由于各种数据库对日期型的定义和处理是不一样的,各种语言对日期型数据的定义的处理也各不相同,因为,我宁愿将日期型数据转换成长整型再保存到数据库中。虽然也可以使用字符串来保存,但使用字符串也会涉及到许多问题,如区域等问题,而且,它需要比保存长整型数据更多的空间。

日期型数据,在 c# 中的参与运算的时候,应该也是转换为长整型数据来运算的。它的长整型值是自 0001 年 1 月 1 日午夜 12:00 以来所经过时间以 100 毫微秒为间隔表示时的数字。这个数在 c# 的 datetime 中被称为 ticks(刻度)。datetime 类型有一个名为 ticks 的长整型只读属性,就保存着这个值。如此,要从一个 datatime 型数据得到 long 型值就非常简单了,只需要读出 datatime 对象的 ticks 值即可,如:

long longdate = datetime.now.ticks;

datetime 的构造函数中也提供了相应的,从长整型数据构造 datetime 型数据的函数:datetime(long)。如:

datetime thedate = new datetime(longdate);

但这样对于很多 vb6 程序员来说,是给他们出了一道难题,因为 vb6 中的日期型数据内部是以 double 型表示的,将其转换为长整型后得到的仅仅是日期,而没有时间。如何协调这两种日期类型呢?
system.datetime 提供了 double tooadate() 和 static datetime fromoadate(double) 两个函数来解决这个问题。前者将当前对象按原来的 double 值输出,后者则从一个 double 值获得一个 system.datetime 对象。举例如下:

private void testdatetimelong() {
double doubledate = datetime.now.tooadate();
datetime thedate = datetime.fromoadate(doubledate);
this.textbox1.text = "";
this.textbox1.appendtext("double value of now: " + doubledate.tostring() + "\n");
this.textbox1.appendtext("datetime from double value: " + thedate.tostring() + "\n");
}

运行结果:

double value of now: 37494.661541713
datetime from double value: 2002-8-26 15:52:37

【相关文章】好搜一下
C#3.0语言详解之基本的语言增强

C#3.0语言详解之基本的语言增强

Linq项目简介和开发环境的搭建9月份,微软推出了一项名为“Linq项目”的新技…