C#学习(二)类型转换
来源:菜鸟教程
C# 类型转换
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式:
- 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
- 显式类型转换 - 显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换会造成数据丢失。
C# 类型转换方法
C# 提供了下列内置的类型转换方法:
序号 | 方法 & 描述 |
---|---|
1 | ToBoolean 如果可能的话,把类型转换为布尔型。 |
2 | ToByte 把类型转换为字节类型。 |
3 | ToChar 如果可能的话,把类型转换为单个 Unicode 字符类型。 |
4 | ToDateTime 把类型(整数或字符串类型)转换为 日期-时间 结构。 |
5 | ToDecimal 把浮点型或整数类型转换为十进制类型。 |
6 | ToDouble 把类型转换为双精度浮点型。 |
7 | ToInt16 把类型转换为 16 位整数类型。 |
8 | ToInt32 把类型转换为 32 位整数类型。 |
9 | ToInt64 把类型转换为 64 位整数类型。 |
10 | ToSbyte 把类型转换为有符号字节类型。 |
11 | ToSingle 把类型转换为小浮点数类型。 |
12 | ToString 把类型转换为字符串类型。 |
13 | ToType 把类型转换为指定类型。 |
14 | ToUInt16 把类型转换为 16 位无符号整数类型。 |
15 | ToUInt32 把类型转换为 32 位无符号整数类型。 |
16 | ToUInt64 把类型转换为 64 位无符号整数类型。 |
说明:
显式转换:通过用户使用预定义的函数显式完成的,显式转换需要强制转换运算符。
转换类型的范围大小和从属关系和隐式转换相反。显式转换可能会导致数据出错,或者转换失败,甚至无法编译成功。
实例:
double dnum = 100.1;
int ifromd = (int)dnum; //double类型显式转换转为int类型
Class1 c11 = new Class1();
Class2 c22 = c11 as Class2; //使用as进行显式转换
Console.WriteLine(c22 is Class1);
Console.WriteLine(c22 is Class2);
运行结果:
FALSE
FALSE
类型之间的转换 - Convert 和 Parse
string locstr = 123.ToString();
//如果要将"locstr"转成整型数
//方法一: 用 Convert
int i = Convert.ToInt16(locstr);
//方法二: 用 Parse
int ii = int.Parse(locstr);
int.TryParse(string s,out int i)
该方式也是将数字内容的字符串转换为int类型,但是该方式比int.Parse(string s) 好一些,它不会出现异常,最后一个参数result是输出值,如果转换成功则输出相应的值,转换失败则输出0。
class test
{
static void Main(string[] args)
{
string s1="abcd";
string s2="1234";
int a,b;
bool bo1=int.TryParse(s1,out a);
Console.WriteLine(s1+" "+bo1+" "+a);
bool bo2=int.TryParse(s2,out b);
Console.WriteLine(s2+" "+bo2+" "+b);
}
}
结果输出:
abcd False 0
1234 True 1234
C# 中对 double 类型的数据取整,可以使用 convert.toint32() 方法,也可使用 int 强制转换为整数,使用 int 时并不存在四舍五入的情况,而是直接将后面的小数位数丢掉。
class Program
{
static void Main(string[] args)
{
double a = 1.35;
double b = 1.65;
int a1 = Convert.ToInt32(a);
int a2 = (int)(a);
int b1 = Convert.ToInt32(b);
int b2 = (int)(b);
Console.WriteLine("{0}使用convert方法转化的结果为:{1}",a,a1);
Console.WriteLine("{0}使用int强制转换的结果为:{1}",a,a2);
Console.WriteLine("{0}使用convert方法转化的结果为:{1}", b, b1);
Console.WriteLine("{0}使用int强制转换的结果为:{1}", b, b2);
Console.ReadKey();
}
}
Convert.ToInt32() 与 int.Parse() 的区别
没搞清楚 Convert.ToInt32 和 int.Parse() 的细细微区别时千万别乱用,否则可能会产生无法预料的结果,举例来说:假如从 url 中取一个参数 page 的值,我们知道这个值是一个 int,所以即可以用 Convert.ToInt32(Request.QueryString["page"]),也可以用 int.Parse(Request.QueryString["page"]),但是如果 page 这个参数在 url 中不存在,那么前者将返回 0,0 可能是一个有效的值,所以你不知道 url 中原来根本就没有这个参数而继续进行下一下的处理,这就可能产生意想不到的效果,而用后一种办法的话没有 page 这个参数会抛出异常,我们可以捕获异常然后再做相应的处理,比如提示用户缺少参数,而不是把参数值当做 0 来处理。
(1) 这两个方法的最大不同是它们对 null 值的处理方法: Convert.ToInt32(null) 会返回 0 而不会产生任何异常,但 int.Parse(null) 则会产生异常。
(2) 对数据进行四舍五入时候的区别
- a. Convert.ToInt32(double value) 如果 value 为两个整数中间的数字,则返回二者中的偶数;即 3.5 转换为 4,4.5 转换为 4,而 5.5 转换为 6。不过 4.6 可以转换为 5,4.4 转换为 4 。
- b. int.Parse("4.5") 直接报错:"输入字符串的格式不正确"。
- c. int(4.6) = 4 Int 转化其他数值类型为 Int 时没有四舍五入,强制转换。
(3) 对被转换类型的区别 int.Parse 是转换 String 为 int, Convert.ToInt32 是转换继承自 Object 的对象为 int 的(可以有很多其它类型的数据)。你得到一个 object 对象, 你想把它转换为 int, 用 int.Parse 就不可以, 要用 Convert.ToInt32。
1)对于转换对象,Convert.ToInt32() 可以为多种类型(例出数字类型外 bool,DateTime 等),int.TryParse() 和 int.Parse() 只能是整型字符串类型(即各种整型 ToString() 之后的形式,不能为浮点型,否则 int.Parse() 就会出现输入的字符串格式不正确的错误,int.TryParse() 也会返回 false,输出参数为 0 ,(int)只能是数字类型(例 float,int,uint等);
2)对于空值 NULL,从运行报错的角度讲,(int) 强制转换和 int.Parse() 都不能接受 NULL;Convert.ToInt32() 其实是在转换前先做了一个判断,参数如果为 NULL,则直接返回 0,否则就调用 int.Parse() 进行转换,int.TryParse() 其实是对 int.Parse() 做了一个异常处理,如果出现异常则返回 false,并且将输出参数返回 0;
3)针对于浮点型的取舍问题,浮点型只有 Convert.ToInt32() 和 (int) 能进行转换,但是也是进行取舍了的,Convert.ToInt32() 采取的取舍是进行四舍五入,而 (int) 则是截取浮点型的整数部分,忽略小数部分,例如 Convert.ToInt32(1.499d) 和 (int)1.499d 都返回 1,Convert.ToInt32(1.5d) 返回 2,而 (int)1.5d 还是返回 1;
4)关于溢出,将大的数据类型转换为小的数据类型时 Convert.ToInt32() 和 int.Parse() 都会报溢出错误,值对于 Int32 太大或太小,而 (int) 不报错,但是返回值为 -1。
如此可见,我们在进行数据转换前选择转换方法要谨慎,如果是数字类型可以考虑直接用(int)强制转换,如果是整型字符串类型的,考虑用 int.Parse() 进行转换,如果不是这两种类型,再考虑用 Convert.ToInt32() 进行转换。