CSharp(六) 类型转换
CSharp 类型转换主要分类两大类: 隐式转换和显示转换
隐式转换
自定完成 无需额外代码,不会丢失数据
- 举例如下
// 小范围类型 → 大范围类型
int num = 100;
long bigNum = num; // int → long
float f = 3.14f;
double d = f; // float → double
// 子类 → 父类
object obj = num; // 任何类型 → object
隐式转换规则
- 小扩大可以.大扩小不行
| 从 | 可隐式转换为 |
|---|---|
| byte | short , int , long , float , double , decimal |
| short | int , long , float , double , decimal |
| int | long , float , double , decimal |
| float | double |
| char | int , long , float , double , decimal |
显式转换
需要手动转换,可能会丢失数据
强制转换(Cast)
用括号()包裹,可能会丢失数据
// 大范围 → 小范围
double d = 3.99;
int i = (int)d; // 截断小数,i = 3
long big = 1000000;
int small = (int)big; // 可能溢出
// 父类 → 子类
object obj = "hello";
string str = (string)obj;
Convert 类转换
- Convert 类提供了一系列的静态方法,用于将不同类型的值转换为其他类型
| 方法 | 说明 |
|---|---|
| ToInt16() | 转换为 short |
| ToInt32() | 转换为 int |
| ToInt64() | 转换为 long |
| ToSingle() | 转换为 float |
| ToDouble() | 转换为 double |
| ToDecimal() | 转换为 decimal |
| ToBoolean() | 转换为 bool |
| ToString() | 转换为 string |
| ToDateTime() | 转换为 DateTime |
| ToChar() | 转换为 char |
- 代码如下
// 各种类型之间的转换
string s = "123";
int num = Convert.ToInt32(s); // 字符串 → int
double d = Convert.ToDouble("3.14"); // 字符串 → double
bool b = Convert.ToBoolean(1); // 非零 → true
string str = Convert.ToString(100); // 任意类型 → 字符串
// 处理 null
string nullStr = null;
int result = Convert.ToInt32(nullStr); // 返回 0,不会报错
Parse 方法转换
- 代码如下
// 字符串 → 数值类型
int num = int.Parse("123");
double d = double.Parse("3.14159");
decimal money = decimal.Parse("199.99");
DateTime date = DateTime.Parse("2024-01-01");
// 注意:Parse 对格式要求严格,输入非法会抛异常
// int.Parse("abc"); // 抛出 FormatException
// int.Parse(null); // 抛出 ArgumentNullException
TryParse 方法转换(最安全)
- 转换成功返回True,失败返回False
// 转换成功返回 true,失败返回 false,不抛异常
string input = "123";
if (int.TryParse(input, out int result))
{
Console.WriteLine($"转换成功: {result}");
}
else
{
Console.WriteLine("转换失败,输入不是有效的整数");
}
// 简洁写法(C# 7.0+)
if (int.TryParse(input, out var num))
{
Console.WriteLine(num);
}
// 旧版本兼容写法
int number;
if (int.TryParse(input, out number)) { }
其他转换方式
as运算符(引用类型/可空类型)
// 用于引用类型转换,失败返回 null 不抛异常
object obj = "hello";
// 方式1:强制转换(失败抛异常)
string str1 = (string)obj;
// 方式2:as 转换(失败返回 null)
string str2 = obj as string; // 成功
// int num = obj as int; // 编译错误!as 只能用于引用类型
// 常用于类型判断
if (obj is string s)
{
Console.WriteLine(s.Length);
}
is 运算符 + 模式匹配(C# 7.0+)
object obj = 123;
// 传统写法
if (obj is int)
{
int num = (int)obj;
}
// 模式匹配(推荐)
if (obj is int num)
{
Console.WriteLine(num);
}
// switch 模式匹配
switch (obj)
{
case int i:
Console.WriteLine($"整数: {i}");
break;
case string s:
Console.WriteLine($"字符串: {s}");
break;
case null:
Console.WriteLine("空值");
break;
}
ToString 方法转换
- 代码如下:
// 任何类型 → 字符串
int num = 100;
string s1 = num.ToString(); // "100"
string s2 = 3.14.ToString("F2"); // "3.14"
string s3 = true.ToString(); // "True"
string s4 = DateTime.Now.ToString("yyyy-MM-dd"); // "2024-01-01"
装箱与拆箱(值类型-引用类型)
// 装箱:值类型 → object
int i = 123;
object boxed = i; // 装箱
// 拆箱:object → 值类型
int j = (int)boxed; // 拆箱,必须强制转换
// 注意:拆箱只能拆回原始类型
// long l = (long)boxed; // 运行时错误!
练习
class Program
{
static void Main()
{
string input = "100";
// 方法1:Convert(处理 null 返回默认值)
int a = Convert.ToInt32(input);
// 方法2:Parse(格式错误抛异常)
int b = int.Parse(input);
// 方法3:TryParse(安全,推荐)
if (int.TryParse(input, out int c))
{
Console.WriteLine($"TryParse 结果: {c}");
}
// 强制转换(数值类型之间)
double d = 99.99;
int truncated = (int)d; // 99,截断小数
// as 运算符(引用类型)
object obj = "test";
string str = obj as string;
// 模式匹配
if (obj is string s)
{
Console.WriteLine(s.ToUpper());
}
}
}
常见错误
// 错误1:溢出
int big = 3000000000; // 编译错误,超出 int 范围
// 错误2:精度丢失(编译器不会警告)
int i = (int)3.99; // i = 3,小数丢失
// 错误3:格式错误
int.Parse("12.5"); // FormatException
int.Parse("abc"); // FormatException
// 错误4:空值
int.Parse(null); // ArgumentNullException
Convert.ToInt32(null); // 返回 0,安全
总结
| 场景 | 推荐方式 |
|---|---|
| 符串 → 数值,用户输入 | TryParse |
| 字符串 → 数值,确定格式正确 | Parse 或 Convert |
| 数值类型之间 | 强制转换 (type) |
| 引用类型转换 | as 或 is 模式匹配 |
| 任意类型 → 字符串 | ToString() |
| 需要处理 null | Convert (返回默认值) |
| 装箱/拆箱 | 尽量避免,影响性能 |