C# 类型转换
隐式转换、显式强制、`Convert`、`Parse`/`TryParse`、装箱拆箱。
Key Points字符串转数字用 `TryParse`,别用 `Parse` —— 后者遇到脏数据直接抛异常。
隐式转换
C#
int a = 100;
long b = a; // int → long,安全
double c = b; // long → double,安全
Console.WriteLine($"{a} {b} {c}");Output
100 100 100Widening conversions are implicit (int→long→float→double). The reverse must be explicit because data can be lost.
显式强制
C#
double d = 3.99;
int i = (int)d; // 截断,不是四舍五入
Console.WriteLine(i);
long big = 300;
byte small = (byte)big; // 溢出:截断低 8 位
Console.WriteLine(small);
// checked 会让溢出抛异常
try
{
byte s2 = checked((byte)big);
}
catch (OverflowException)
{
Console.WriteLine("溢出被捕获");
}Output
3
44
溢出被捕获字符串与数字
C#
// Parse:失败抛异常
int n1 = int.Parse("42");
Console.WriteLine(n1);
// TryParse:失败返回 false,不抛异常(推荐)
if (int.TryParse("4x", out int n2))
{
Console.WriteLine($"解析成功 {n2}");
}
else
{
Console.WriteLine("解析失败");
}
// Convert:能处理 null
Console.WriteLine(Convert.ToInt32(null));
Console.WriteLine(Convert.ToInt32("123"));Output
42
解析失败
0
123| Method | On failure | Null input |
|---|---|---|
Parse | 抛 FormatException | 抛 ArgumentNullException |
TryParse | 返回 false | 返回 false |
Convert | 抛异常 | 返回 0 |
**Use
TryParse for any external input.** Forms, config files and CSVs contain anything; Parse lets one dirty field crash the request.数字转字符串
C#
int n = 42;
Console.WriteLine(n.ToString());
Console.WriteLine(n.ToString("D5")); // 补零
Console.WriteLine(n.ToString("X")); // 十六进制
double pi = 3.14159;
Console.WriteLine(pi.ToString("F2")); // 两位小数
Console.WriteLine(pi.ToString("P1")); // 百分比
decimal money = 1234.5m;
Console.WriteLine(money.ToString("C")); // 货币Output
42
00042
2A
3.14
314.2%
¥1,234.50装箱与拆箱
C#
int i = 42;
object boxed = i; // 装箱:值类型 → 引用类型,堆分配
int unboxed = (int)boxed; // 拆箱:引用类型 → 值类型
Console.WriteLine($"{boxed} {unboxed}");
// 拆箱类型必须完全匹配
try
{
long wrong = (long)boxed;
}
catch (InvalidCastException)
{
Console.WriteLine("拆箱类型不匹配");
}Output
42 42
拆箱类型不匹配Boxing allocates on the heap and unboxing type-checks — both cost. Looping over an ArrayList of value types is dozens of times slower, which is one reason List<T> exists.
隐式转换
C#
int a = 100;
long b = a; // int → long,安全
double c = b; // long → double,安全
Console.WriteLine($"{a} {b} {c}");Output
100 100 100小范围转大范围是隐式的(int→long→float→double)。反过来必须显式,因为可能丢数据。
显式强制
C#
double d = 3.99;
int i = (int)d; // 截断,不是四舍五入
Console.WriteLine(i);
long big = 300;
byte small = (byte)big; // 溢出:截断低 8 位
Console.WriteLine(small);
// checked 会让溢出抛异常
try
{
byte s2 = checked((byte)big);
}
catch (OverflowException)
{
Console.WriteLine("溢出被捕获");
}Output
3
44
溢出被捕获字符串与数字
C#
// Parse:失败抛异常
int n1 = int.Parse("42");
Console.WriteLine(n1);
// TryParse:失败返回 false,不抛异常(推荐)
if (int.TryParse("4x", out int n2))
{
Console.WriteLine($"解析成功 {n2}");
}
else
{
Console.WriteLine("解析失败");
}
// Convert:能处理 null
Console.WriteLine(Convert.ToInt32(null));
Console.WriteLine(Convert.ToInt32("123"));Output
42
解析失败
0
123| 方法 | 失败时 | null 输入 |
|---|---|---|
Parse | 抛 FormatException | 抛 ArgumentNullException |
TryParse | 返回 false | 返回 false |
Convert | 抛异常 | 返回 0 |
**处理外部输入一律用
TryParse**。用户填的表单、配置文件、CSV 里什么都可能有,Parse 会让一个脏字段把整个请求打挂。数字转字符串
C#
int n = 42;
Console.WriteLine(n.ToString());
Console.WriteLine(n.ToString("D5")); // 补零
Console.WriteLine(n.ToString("X")); // 十六进制
double pi = 3.14159;
Console.WriteLine(pi.ToString("F2")); // 两位小数
Console.WriteLine(pi.ToString("P1")); // 百分比
decimal money = 1234.5m;
Console.WriteLine(money.ToString("C")); // 货币Output
42
00042
2A
3.14
314.2%
¥1,234.50装箱与拆箱
C#
int i = 42;
object boxed = i; // 装箱:值类型 → 引用类型,堆分配
int unboxed = (int)boxed; // 拆箱:引用类型 → 值类型
Console.WriteLine($"{boxed} {unboxed}");
// 拆箱类型必须完全匹配
try
{
long wrong = (long)boxed;
}
catch (InvalidCastException)
{
Console.WriteLine("拆箱类型不匹配");
}Output
42 42
拆箱类型不匹配装箱要在堆上分配对象,拆箱要类型检查,都有开销。在循环里对值类型做 ArrayList 操作会慢几十倍——这就是泛型 List<T> 存在的理由之一。