C#中的数据类型转换
C# 是一门强类型语言,对类型的要求很严格,类型转换的方式有两种:隐式类型转换和显式类型转换。
隐式类型转换
1 | int a = 5; |
像这样,并没有在源代码里进行任何特殊处理,而是由编译器自动进行了从int
类型到double
类型的隐式转换。
但是很多类型之间不可以进行隐式类型转换,可以看下面的例子。
1 | int a = 1.5; |
在作者的电脑上编译时会有这样的报错:
error CS0266: 无法将类型“double”隐式转换为“int”。存在一个显式转换(是否缺少强制转换?)
因此,我们需要用显式类型转换改正它。
显式类型转换
上面的例子的第一行应改为这样:
1 | int a = (int)1.5; |
语法就是在要转换的变量前加一组小括号,里面写要转换成的类型名。所有的隐式类型转换都可以写成显式。
但是这样写输出的结果却是1
而非四舍五入的2
用显式类型转换会丢失数据的精度,这也是为什么不会自动进行显式类型转换。显式类型转换又叫强制类型转换。
而且显式类型转换也并非所有类型之间都能转的,例如下面这么写也是错误的:
1 | double a = (double)"5.5"; |
在许多其他编程语言里,int
可以隐式转换为bool
,但是 C# 中无论是隐式还是显式都会报错,要使用后面提到的Convert.ToBoolean()
为了解决上述的问题,我们将介绍使用方法进行类型转换。
使用方法进行类型转换
使用ToString()
方法
所有的类型都可以使用ToString()
方法(因为 Object
类定义了 ToString
方法,而所有类都直接或者间接派生自 Object
类),如下:
1 | int a = 5; |
使用Convert.ToInt32()
方法
Convert
类提供了许多转换的方法,例如:ToChar()
,ToDouble()
,ToBoolean()
甚至 ToDateTime()
1 | int a = Convert.ToInt32("55"); |
使用Type.Parse(string)
方法
Parse()
方法用来将字符串转换为其他的数值类型
Parse()
方法的参数只能是字符串
而 Type
只能是数字类型
使用时 类型名.Parse(需要转换的变量);
即可
例如:
1 | string a = "5"; |
注意事项
试图将字符串"5.5"
转换成int
类型时,下面两种方法都是错误的:
1 | int a = Convert.ToInt32("5.5"); |
正确的做法应该是先把字符串 "5.5"
转换成 double
类型,再转换成 int
类型:
1 | int a = (int)Convert.ToDouble("5.5"); |
进行从字符串到数值类型转换时 Convert
和 Parse
做法一般可以互换, 区别在于对 null
的处理不同:
1 | int a = Convert.ToInt32(null); // a == 0 |
另外, 传入空字符串 ""
时两者都会抛出异常
如果您希望自己封装的类可以被 Convert
类转换为基本类型, 请继承IConvertible
接口, 如果你觉得有些类型不应该被转化(点名ToDateTime
), 请抛出 InvalidCastException
异常
使用 int.TryParse()
方法
微软官方教程中的说明如下:
TryParse()
方法可同时执行多项操作:
它会尝试将字符串分析成给定的数字数据类型。
如果成功,它会将转换后的值存储在 out 参数中。
它会返回布尔值来指示操作是否成功。
对于所有数字数据类型,均可使用类似的
TryParse()
方法。
其实多写一个try catch就解决了, 没什么用
例如:
1 | double result; |
此时,输出结果应为:
1 | a = True |
out
关键字的用法类似 ref
关键字, 本质上都是传入引用, 且都需要在方法的定义和调用时显式使用该关键字
主要的区别为:
- 使用
ref
必须在传参之前进行显式的初始化, 而out
有没有都行 - 离开方法之前必须对有
out
关键字的参数赋值(否则通不过编译) - 使用
out
的参数在方法中被视为未被初始化的 - 尽管你可以给传入赋值过的变量, 但在传入时参数的值是没有意义的
另外, out
其实就是用 ref
来实现的, 所以不可以像 Func(ref int a)
Func(out int a)
这样重载
示例(来自微软官方文档 链接)
已知一个字符串数组 values
1 | string[] values = { "12.3", "45", "ABC", "11", "DEF" }; |
循环访问字符串数组中的每个值:如果值是字母,则连接它以形成消息;如果值是数字,则将其加到总计值
输出:
Message: ABCDEF
Total: 68.3
示例代码:
1 | using System; |