数据类型转换与进制转换

2.5.1    数值类型转换

数值类型转换分为两种:隐式转换、强制转换(显式转换)。

隐式转换

只要能保证值不会发生改变,类型转换就可以自动(隐式)进行。所以,只能从较小的整数类型隐式的转换为较大的整数类型。

 1         static void Main(string[] args)
 2         {
 3             byte b = 24;//byte类型,8位无符号整数
 4             int i = 100;//int类型,32位无符号整数
 5             double d = 30.3;//double类型,64位双精度浮点数
 6 
 7             i = b;//byte --> int  可以进行隐式转换
 8             d = i;//int --> double  可以进行隐式转换
 9 
10             //i = d;//double --> int  不能隐式转换,会发生数据丢失(丢失小数部分)
11             //b = i;//int --> byte  不能隐式转换,会发生数据丢失(丢失3个字节的数据)
12         }

 

但是有一中比较特殊的情况:

 1         static void Main(string[] args)
 2         {
 3             byte num1 = 20;
 4             byte num2 = 10;
 5 
 6             short sh1 = 30;
 7             short sh2 = 40;
 8 
 9             char ch1 = 'a';
10             char ch2 = 'b';
11 
12 
13             //byte res1 = num1 + num2;//错误:无法将类型int隐式转化为int
14             //short res2 = sh1 + sh2;//错误:无法将类型int隐式转化为short
15             //char res3 = ch1 + ch2;//错误:无法将类型int隐式转化为char
16 
17             int res1 = num1 + num2;//正确
18             int res2 = sh1 + sh2;//正确
19             int res3 = ch1 + ch2;//正确
20 
21             Console.WriteLine(res1 + ":" + res2 + ":" + res3);//30:70:195
22             Console.ReadKey();
23         }

 

 

我们从错误可以推断出,byte、short、char类型的数值求和结果的类型为int类型,而不再是他们本身的类型了,为什么会出现这种情况呢?

原因是byte、short类型所表示的数值的范围比较小,例如,byte类型只能表示0-255的整数,两个byte类型的数字相加,很有可能就超出了byte类型的表示范围;所以当程序运行时,会将结果的类型隐式的转换为int类型;此时如果将结果赋值给一个int类型的变量,自然就会报错。

显式转换

有时我们需要进行类型转换,即时知道可能存在数据丢失的情况,例如将double类型的数值转换为int类型;此时,我们就需要使用显式转换,或者叫强制类型转换。

显式类型转换就是在需要转换的类型前面通过一对(),为其指定要转换的目标类型:

 1         static void Main(string[] args)
 2         {
 3             int num1 = 30;
 4             double num2 = 40.49;
 5 
 6             num1 = (int)num2;
 7 
 8             Console.WriteLine(num1);//40
 9 
10             Console.ReadKey();
11         }

 

但是,所有的显式类型转换都是可能不安全的。

1         static void Main(string[] args)
2         {
3             long num1 = 3000000000;
4             int num2 = (int)num1;
5 
6             Console.WriteLine(num2);//-1294967296
7 
8             Console.ReadKey();
9         }

 

当进行long和int类型的转换时,如果long类型的数值,比int类型所能表示的最大值还大,就会出现上边的情况。所以在应用程序中应该包含代码来处理可能失败的类型转换。

C#提供了一个checked运算符,使用它可以测试操作是否会导致算数溢出,可以检查类型强制转换是否安全,如果不安全,就可以抛出一个异常。

 1         static void Main(string[] args)
 2         {
 3             long num1 = 3000000000;
 4             int num2;
 5             checked
 6             {
 7                 num2 = (int)num1;//异常:算术运算导致溢出
 8             }
 9 
10             Console.WriteLine(num2);
11 
12             Console.ReadKey();
13         }

 

用户自定义的类型强制转换

C#允许进行两种不同数据类型的强制转换:隐式强制转换和显式强制转换。

如果源数据值会使类型强制转换失败,后者可能会抛出异常,就应把任何自定义的类型强制转换定义为显式强制转换;并且不能同时定义隐式强制类型转换和显示强制类型转换。

定义类型强制转换的语法类似于重载运算符,下面的代码定义了隐式强制类型转换(implicit)。

 1     class Boy
 2     {
 3         public string name;
 4         public int age;
 5         public Boy(string name, int age)
 6         {
 7             this.name = name;
 8             this.age = age;
 9         }
10         /// <summary>
11         /// 定义 Boy-->Girl 的隐式强制类型转换方式
12         /// </summary>
13         /// <param name="boy">源类型</param>
14         /// <returns></returns>
15         public static implicit operator Girl(Boy boy)
16         {
17             return new Girl(boy.name, boy.age);
18         }
19         /// <summary>
20         /// 定义 Girl --> Boy 的隐式强制类型转换方式
21         /// </summary>
22         /// <param name="girl">源类型</param>
23         /// <returns></returns>
24         public static implicit operator Boy(Girl girl)
25         {
26             return new Boy(girl.name, girl.age);
27         }
28     }
29 
30     class Girl
31     {
32         public string name;
33         public int age;
34         public Girl(string name, int age)
35         {
36             this.name = name;
37             this.age = age;
38         }
39     }
40 
41     class Program
42     {
43         static void Main(string[] args)
44         {
45             Boy boy = new Boy("张三", 20);
46             Girl girl = boy;
47 
48             Girl g = new Girl("李四", 30);
49             Boy b = g;
50 
51             Console.WriteLine(girl.name + ":" + girl.age);
52             Console.WriteLine(b.name + ":" + b.age);
53 
54             Console.ReadKey();
55         }
56     }

 

定义显式强制类型转换,代码如下(explicit):

 1     class Boy
 2     {
 3         public string name;
 4         public int age;
 5         public Boy(string name, int age)
 6         {
 7             this.name = name;
 8             this.age = age;
 9         }
10     }
11 
12     class Girl
13     {
14         public string name;
15         public int age;
16         public Girl(string name, int age)
17         {
18             this.name = name;
19             this.age = age;
20         }
21         /// <summary>
22         /// 定义 Boy --> Girl 的显式强制类型转换方法
23         /// </summary>
24         /// <param name="boy">源类型</param>
25         /// <returns></returns>
26         public static explicit operator Girl(Boy boy)
27         {
28             return new Girl(boy.name, boy.age);
29         }
30         /// <summary>
31         /// 定义 Girl --> Boy 的显式强制类型转换方法
32         /// </summary>
33         /// <param name="boy">源类型</param>
34         /// <returns></returns>
35         public static explicit operator Boy(Girl girl)
36         {
37             return new Boy(girl.name, girl.age);
38         }
39     }
40 
41     class Program
42     {
43         static void Main(string[] args)
44         {
45             Boy boy = new Boy("张三", 20);
46             Girl girl = (Girl)boy;
47 
48             Girl g = new Girl("李四", 30);
49             Boy b = (Boy)g;
50 
51             Console.WriteLine(girl.name + ":" + girl.age);
52             Console.WriteLine(b.name + ":" + b.age);
53 
54             Console.ReadKey();
55         }
56     }

 

自定义的类型转换要求放在源类或者目标类中,不可以放在其他地方。

 

常用的基本类型转换:

源类型

目标类型

转换方法

示例

bool、byte、char、double、decimal、float、long、short、sbyte、string、int、ulong、ushort

int

Convert.ToInt32(Type value)

int num = Convert.ToInt32("30");

string

int

int.Parse(string s)

int num = int.Parse("20");

string

int

int.TryPase(string s,out int result)

int num = 0;
if (int.TryParse("20", out num))
{
    //类型转化成功,变量num中的值为20;
}
else
{
    //类型转化失败,变量num中的值为0;
}

bool、byte、char、DateTime、decimal、double、float、int、long、sbyte、short、uint、ulong、ushort

string

Type.ToString()

ushort sh = 9;
Console.WriteLine(sh.ToString());

char[]

string

new string()

char[] ch = new char[] { 'a', 'b', 'c','d' };
string str = new string(ch);

byte[]

string

Encoding.Default.GetString()

byte[] by = { 97, 98, 99, 100 };
string str = Encoding.Default.GetString(by);

byte、decimal、double、float、int、long、sbyte、short、string、uint、ulong、ushort

bool

Convert.ToBoolean()

string str = "false";
int i = 20;//零为False,非零为True
bool bo = Convert.ToBoolean(str);
bool bo2 = Convert.ToBoolean(i);

string

char[]

s.ToArray();

s.ToCharArray()

string str = "abcd";
char[] res;
res = str.ToArray();
res = str.ToCharArray();

byte[]

char[]

Encoding.Default.GetChars()

byte[] by = { 30, 49, 9 };
char[] res = Encoding.Default.GetChars(by);

string

byte[]

Encoding.Default.GetBytes()

string str = "abcd";
byte[] res = Encoding.Default.GetBytes(str);

char[]

byte[]

Encoding.Default.GetBytes()

char[] ch = { 'a', 'b', 'c' };
byte[] res = Encoding.Default.GetBytes(ch);

2.5.2    进制转换

 1             //二进制-->十进制
 2             Console.WriteLine(Convert.ToInt32("1010", 2));//10
 3             //八进制-->十进制
 4             Console.WriteLine(Convert.ToInt32("21", 8));//17
 5             //十六进制-->十进制
 6             Console.WriteLine(Convert.ToInt32("32", 16));//50
 7             Console.WriteLine(Convert.ToInt32("0x00000032", 16));//50
 8 
 9             //十进制-->十六进制
10             Console.WriteLine(Convert.ToString(20, 16));//14
11             Console.WriteLine(242.ToString("X"));//F2
12             Console.WriteLine(242.ToString("X8"));//000000F2
13             Console.WriteLine(242.ToString("x"));//f2
14             Console.WriteLine(242.ToString("x8"));//000000f2
15             //十进制-->八进制
16             Console.WriteLine(Convert.ToString(15,8));//17
17             //十进制-->二进制
18             Console.WriteLine(Convert.ToString(10, 2));//1010

 

posted @ 2017-07-27 11:38  CS讷于言而敏于行  阅读(1063)  评论(0编辑  收藏  举报