我们从小学就开始知道要数据类型转换,不知道为什么到现在还有程序员在数据类型转换上晕来晕去的。

一头猪+一头羊=?
显然我们要数据类型转换为:(牲口)一头猪+(牲口)一头羊=两头牲口。

在C#中同样如此,在转换中的要领是

大的转小的,隐式转。小的转大的,显示转。

隐式转换 适用于那些不用仔细检查即可安全地实现的转换
总是会成功,而且从不会导致信息丢失
显式转换 换需用强制转换表达式来实现
不完全安全,可能会损失精度
强制转换表达式既可用于显式转换亦可用于隐式转换

另外一个最重要的要领是,转换的两边必须相等。
这个相等是指数据的两边要么是值类型,要么是引用类型。(关于值类型和引用类型我们下一篇马上出来)

 

1数据类型转换 _安全 int i = 10;
2数据类型转换 _安全 int j = i;//赋值的两边都是值类型,成功
3数据类型转换 _安全 i = (int)j;//赋值的两边都是值类型,成功
4数据类型转换 _安全
5数据类型转换 _安全 string n = (string)i;//string是引用类型,int是值类型,两边不平衡。失败
6数据类型转换 _安全
7数据类型转换 _安全 object o = i;
8数据类型转换 _安全 string m = (string)o;//无法将类型为“System.Int32”的对象强制转换为类型“System.String”。失败
9数据类型转换 _安全 j = (int)o;//成功


以上代码告诉我们什么是转换的两边必须相等。

那个大到小是什么意思呢?大容量的数据类型转到小容量的数据类型是要付出精度代价的。记住,我们关注的是容量而不是具体的值。

现看一下基础值的容量范围

 

1数据类型转换 _安全 System.Console.WriteLine("byte:{0}<-->{1}", byte.MaxValue, byte.MinValue);
2数据类型转换 _安全 System.Console.WriteLine("short:{0}<-->{1}", short.MaxValue, short.MinValue);
3数据类型转换 _安全 System.Console.WriteLine("int:{0}<-->{1}", int.MaxValue, int.MinValue);
4数据类型转换 _安全 System.Console.WriteLine("long:{0}<-->{1}", long.MaxValue, long.MinValue);
5数据类型转换 _安全 System.Console.WriteLine("float:{0}<-->{1}", float.MaxValue, float.MinValue);
6数据类型转换 _安全 System.Console.WriteLine("decimal:{0}<-->{1}", decimal.MaxValue, decimal.MinValue);
7数据类型转换 _安全 System.Console.WriteLine("double:{0}<-->{1}", double.MaxValue, double.MinValue);
8数据类型转换 _安全
9数据类型转换 _安全 System.Console.WriteLine("char:{0}<-->{1}", char.MaxValue, char.MinValue);



那么我们来考虑以下代码的输出
 

1数据类型转换 _安全 double d = double.MaxValue;
2数据类型转换 _安全 long l = (long)d;
3数据类型转换 _安全 int i = (int)l;
4数据类型转换 _安全 short s = (short)i;
5数据类型转换 _安全 byte b = (byte)s;
6数据类型转换 _安全 System.Console.WriteLine(b);
7数据类型转换 _安全 System.Console.WriteLine(b==byte.MaxValue);


你是不是会认为目前b的值就是b能容纳的最大值呢?或者你认为会运行错误?
我们要学点推理和思考。以上代码是不是向我们演示了这样一个过程
double.MaxValue-->long.MaxValue-->int.MaxValue-->short.MaxValue-->byte.MaxValue
看上去似乎是的,但是我们来考虑一段代码
 

1数据类型转换 _安全 byte b = 200;
2数据类型转换 _安全 b += 100;
3数据类型转换 _安全 System.Console.WriteLine(b);//输出的结果不是255,也不是错误,是44

现在你冷静考虑一下,是不是感觉到了当数据类型获得了超出资金范围的值以后的处理方式了吗?围绕。
所以刚才代码的演变是
 

1数据类型转换 _安全 double d = double.MaxValue;// d 1.7976931348623157E+308 double
2数据类型转换 _安全 long l = (long)d;//-9223372036854775808
3数据类型转换 _安全 int i = (int)l;//0
4数据类型转换 _安全 short s = (short)i;//0
5数据类型转换 _安全 byte b = (byte)s;//0
6数据类型转换 _安全 System.Console.WriteLine(b);
7数据类型转换 _安全 System.Console.WriteLine(b == byte.MaxValue);



关于数据类型转变,还有一个重要的现象
 

1数据类型转换 _安全 byte b = 10;
2数据类型转换 _安全 b = b + 100;//无法将类型“int”隐式转换为“byte”
3数据类型转换 _安全 b += 100;//通过

原因是+是运算符,运算符的左右要类型一致,所以编译器要转为b=(int)b+100;这样结果就是int了,int比byte大,所以不能直接赋值为b,编译错误。 要改为b =(byte) ((int)b + 100);
而+=和=都是赋值运算,编译会做可能的转换试探。

关于char和int的转换,有C经验的都知道其实他们都一样
 

1数据类型转换 _安全 for (int i = 'a'; i <= 'z'; i++)
2数据类型转换 _休闲_40 {
3数据类型转换 _安全_43 char c = (char)i;
4数据类型转换 _安全_43 System.Console.WriteLine(c);
5数据类型转换 _数据_45 }

6数据类型转换 _安全
7数据类型转换 _安全 for (char c = 'a'; c <= 'z'; c++)
8数据类型转换 _表达式_48 {
9数据类型转换 _安全_43 System.Console.WriteLine(c);
10数据类型转换 _数据_45 }

以上两段代码的效果一样。

初学者对于C#的字符串转数字之类的总感觉很迷惑,int i = (int)"123";使错误的,所以有同学用System.Convert.ToInt32("123");哎,这个也太累了。基础数据其实都提供了字符串的转换能力。

1数据类型转换 _安全 System.Console.WriteLine(byte.Parse("123"));
2数据类型转换 _安全 System.Console.WriteLine(short.Parse("123"));
3数据类型转换 _安全 System.Console.WriteLine(int.Parse("123"));
4数据类型转换 _安全 System.Console.WriteLine(long.Parse("123"));
5数据类型转换 _安全 System.Console.WriteLine(float.Parse("123"));
6数据类型转换 _安全 System.Console.WriteLine(decimal.Parse("123"));
7数据类型转换 _安全 System.Console.WriteLine(double.Parse("123"));

2005还提供了Tryparse的方法,可以让你不至于出去转换异常。