C# 类型转换

隐式转换、显式强制、`Convert`、`Parse`/`TryParse`、装箱拆箱。

Beginner
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 100

Widening 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
MethodOn failureNull 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.

Friends & Partners