类型转换
隐式转换
隐式转换是编译器自动执行的类型转换,不需要额外语法。它发生在从小范围类型到大范围类型的赋值中,不会丢失数据。
转换规则
int→longint→doublefloat→double- 任何类型 →
string(通过ToString())
示例
CSHARP
int a = 100;
long b = a;
int c = 42;
double d = c;
float e = 3.14f;
double f = e;
int g = 99;
string h = g.ToString();
Console.WriteLine($"int→long: {b}");
Console.WriteLine($"int→double: {d}");
Console.WriteLine($"float→double: {f}");
Console.WriteLine($"int→string: {h}");
TEXT
int→long: 100
int→double: 42
float→double: 3.14
int→string: 99
显式转换
显式转换需要使用强制转换语法,即在值前加上目标类型。它发生在从大范围类型到小范围类型的赋值中,可能会丢失数据。
语法
CSHARP
目标类型 变量 = (目标类型)值;
示例
CSHARP
double pi = 3.14;
int truncated = (int)pi;
int number = 42;
double widened = (double)number;
long big = 3000000000L;
int overflow = (int)big;
Console.WriteLine($"(int)3.14 → {truncated}");
Console.WriteLine($"(double)42 → {widened}");
Console.WriteLine($"(int)3000000000L → {overflow}");
TEXT
(int)3.14 → 3
(double)42 → 42
(int)3000000000L → -1294967296
⚠️ 显式转换可能导致精度丢失或溢出,请务必确认数据范围。
Convert 类
System.Convert 类提供了静态方法,可在各种基础类型之间进行转换,比强制转换更安全且语义更清晰。
常用方法
| 方法 | 说明 |
|---|---|
Convert.ToInt32 |
转换为 int |
Convert.ToDouble |
转换为 double |
Convert.ToString |
转换为 string |
Convert.ToBoolean |
转换为 bool |
示例
CSHARP
string s1 = "42";
string s2 = "3.14";
string s3 = "0";
int n1 = Convert.ToInt32(s1);
double n2 = Convert.ToDouble(s2);
string n3 = Convert.ToString(n1);
bool n4 = Convert.ToBoolean(s3);
bool n5 = Convert.ToBoolean(1);
Console.WriteLine($"ToInt32: {n1}");
Console.WriteLine($"ToDouble: {n2}");
Console.WriteLine($"ToString: {n3}");
Console.WriteLine($"ToBoolean(\"0\"): {n4}");
Console.WriteLine($"ToBoolean(1): {n5}");
TEXT
ToInt32: 42
ToDouble: 3.14
ToString: 42
ToBoolean("0"): False
ToBoolean(1): True
💡
Convert.ToBoolean 对字符串只识别 "True" 和 "False",对数值非零为 true、零为 false。
Parse 与 TryParse
Parse 方法
Parse 将字符串解析为目标类型,格式不合法时抛出 FormatException。
示例
CSHARP
int a = int.Parse("42");
double b = double.Parse("3.14");
Console.WriteLine($"int.Parse: {a}");
Console.WriteLine($"double.Parse: {b}");
TEXT
int.Parse: 42
double.Parse: 3.14
CSHARP
try
{
int bad = int.Parse("hello");
}
catch (FormatException ex)
{
Console.WriteLine($"解析失败: {ex.Message}");
}
TEXT
解析失败: Input string was not in a correct format.
TryParse 方法
TryParse 不会抛出异常,而是通过返回 bool 表示是否成功,解析结果通过 out 参数输出。
示例
CSHARP
if (int.TryParse("42", out int result1))
{
Console.WriteLine($"解析成功: {result1}");
}
if (!int.TryParse("abc", out int result2))
{
Console.WriteLine($"解析失败, result2 = {result2}");
}
TEXT
解析成功: 42
解析失败, result2 = 0
📌 推荐在处理用户输入等不可靠数据时使用
TryParse,避免异常带来的性能开销。
装箱与拆箱
装箱(Boxing)
将值类型转换为 object 引用类型的过程称为装箱。值从栈复制到堆中,产生内存分配。
示例
CSHARP
int value = 42;
object boxed = value;
Console.WriteLine($"装箱: {boxed}, 类型: {boxed.GetType()}");
TEXT
装箱: 42, 类型: System.Int32
拆箱(Unboxing)
将 object 引用类型强制转换回值类型的过程称为拆箱。必须使用显式转换,类型不匹配会抛出 InvalidCastException。
示例
CSHARP
object boxed = 42;
int unboxed = (int)boxed;
Console.WriteLine($"拆箱: {unboxed}");
TEXT
拆箱: 42
CSHARP
object boxed = 42;
try
{
double wrong = (double)boxed;
}
catch (InvalidCastException ex)
{
Console.WriteLine($"拆箱类型不匹配: {ex.Message}");
}
TEXT
拆箱类型不匹配: Specified cast is not valid.
⚠️ 拆箱时目标类型必须与装箱时的原始类型完全一致,否则抛出
InvalidCastException。
类型转换的常见陷阱
浮点数转整数丢失精度
CSHARP
double d = 9.99;
int i = (int)d;
Console.WriteLine($"9.99 → {i}");
TEXT
9.99 → 9
大类型转小类型溢出
CSHARP
long big = 5000000000L;
int small = (int)big;
Console.WriteLine($"5000000000L → {small}");
TEXT
5000000000L → 705032704
Parse 解析非法字符串抛异常
CSHARP
try
{
int n = int.Parse("3.14");
}
catch (FormatException)
{
Console.WriteLine("无法将 \"3.14\" 解析为 int");
}
TEXT
无法将 "3.14" 解析为 int
🔒 避免陷阱的最佳实践:转换前检查数据范围;优先使用
TryParse;对溢出场景使用checked关键字。
❓ 常见问题
Q 隐式转换一定不会丢失数据吗?
A 是的,隐式转换只发生在不会丢失精度或范围的安全转换路径上。
Q:Convert.ToInt32 与 (int) 强制转换有什么区别? A:(int) 是直接截断,Convert.ToInt32 对浮点数使用四舍五入(银行家舍入法)。
Q:装箱和拆箱对性能有什么影响? A:装箱会在堆上分配内存,拆箱需要类型检查和值复制,频繁操作会降低性能。
Q:int.Parse 和 Convert.ToInt32 哪个更好? A:对于字符串输入两者效果类似,但 Convert.ToInt32 对 null 返回 0,而 int.Parse 抛出异常。
Q:TryParse 解析失败时 out 参数的值是什么? A:解析失败时 out 参数被赋值为该类型的默认值,如 int 为 0。
📖 小节
- 隐式转换从小范围到大范围,安全自动
- 显式转换使用强制转换语法,可能丢失精度或溢出
- Convert 类提供跨类型安全转换方法
- Parse 直接解析字符串,失败抛异常;TryParse 安全返回布尔值
- 装箱将值类型包装为堆上的 object,拆箱需类型精确匹配
- 实际开发中优先使用 TryParse,避免异常和隐式装箱
📝 作业
- 编写程序,分别用隐式转换和显式转换将
short值 32767 转为int和将int值 32768 转为short,观察结果 - 使用
Convert.ToInt32对 2.5 和 3.5 进行转换,验证银行家舍入规则 - 编写一个方法,接收 string 参数,使用
TryParse安全解析为int,成功返回解析值,失败返回 -1 - 编写代码演示装箱和拆箱,并故意用错误类型拆箱捕获
InvalidCastException - 使用
checked关键字包裹一个int溢出的强制转换,观察是否抛出OverflowException



