关于C#类型转换的知识点,在各书籍以及博客文章中一抓一大把。那么我为什么又要重复这些文字呢----只因在各类文章中描述的很不错、明了,但是到了实际使用中(写代码)却被自己忽略了。仅此记下。
例如当封装了数据库执行返回受影响行数的方法ExcuteNonQuery使其方法返回了object类型,而到了业务上层,却需要将其转换数值型,或者说直接拆箱成数值型(如int),根据其是否大于零来判断操作是否成功。
当时我的想法是底层ExcuteNonQuery方法返回的是int类型,直接强转
string insertStr="insert into ..." ///插入数据库语句 XXXDal xxxDal=new XXXDal() //Dal底层为orm一封装好了的 object result =xxxDal.ExcuteNonQuery(insertStr) if((int)result>0) { //TODO成功后操作.... } else { }
尼玛报错了,(int)result 类转换错误。原来底层返回的object实为long类型(关于底层为什么要返回long,暂时不去理)。
那时在这个问题上纠结了蛮久的,一、我为什么要这样写?----只是单纯的以为返回受影响行数,应该是int;二、这样写是否合理,别人框架返回一个object,而你需要将其转成int,怎样写才合理?-----1、Convert.ToInt();2、int.TryParse();3、 拆箱强转(需要知道元类型是什么)。
C#类型
值类型
bool -> 布尔型,其值为 true 或者 false
char -> 字符型,占有两个字节,表示 1 个 Unicode 字符(C#中是统一两个字节,不是所谓的中文才两个字节)
byte -> 字节型,占 1 字节,表示 8 位正整数,范围 0 ~ 255
sbyte ->带符号字节型,占 1 字节,表示 8 位整数,范围 -128 ~ 127
ushort -> 无符号短整型,占 2 字节,表示 16 位正整数,范围 0 ~ 65,535
uint -> 无符号整型,占 4 字节,表示 32 位正整数,范围 0 ~ 4,294,967,295
ulong -> 无符号长整型,占 8 字节,表示 64 位正整数,范围 0 ~ 大约 10 的 20 次方
short -> 短整型,占 2 字节,表示 16 位整数,范围 -32,768 ~ 32,767
int -> 整型,占 4 字节,表示 32 位整数,范围 -2,147,483,648 到 2,147,483,647
long -> 长整型,占 8 字节,表示 64 位整数,范围大约 -(10 的 19) 次方 到 10 的 19 次方
float -> 单精度浮点型,占 4 个字节
double -> 双精度浮点型,占 8 个字节
decimal ->128位高精度浮点数,常用于金融运算,不会出现浮点数计算的误差(在CLR中不是基本类型,decimal类型变量的运算不是直接生成IL指令,而是调用System.Decimal结构的方法)
枚举、结构体
引用类型
1、string
2、object
3、类
4、委托
5、接口
6、数组
类型转换
基本类型之间的转换
1、隐式转换:基本上就是位数少的可以隐式的转换成位数长的,非数值型的除外,例如char,bool。当然decimal也要注意。byte, short, int, long, float, double这个顺序前面的类型可以隐式的转成后面类型。
2、显示转换:位数长的类型转换成位数短的类型需要进行显示的转换。当然显示的转换有可能会造成数据的错误,因为数据值在目标类型的范围外时会造成得到的结果错误,而不报异常,可以通过check进行验证捕获异常。
值类型和引用类型的转换
其实也就是所谓的装箱与拆箱。值类型转成引用类型为装箱操作,引用类型转换成值类型则为拆箱操作。值类型位于栈中,而引用类型位于堆中...(关于装箱与拆箱原理,涉及到的内存转换这里就不说了,有很多文章已经说得很清楚了。如《你必须知道的.net》中就写的非常好)。
回过头来
所以现在回过头来,其实上面自己的代码是错误的,object转成数值型,是拆箱操作。强制的拆箱操作只能是先将对象转成原先类型的变量,然后再显示转换成int:
long l=(long) result; //result本身是long装箱而成
int i=(int)l; //显示转换
不过并不需要写得这么麻烦,.net Framework 提供给我们一个很强大的基本类型转换的帮助类:Convert
当然也可以使用int.Parse(result.ToString()); 只是Parse只接受string类型参数。
结论:其实这个问题没什么好纠结的,是把强制类型转换和拆箱弄一块去了。