Skip to content

C# - 类型转换

类型转换,或称类型强制转换 (type casting),是将一个值从一种数据类型转换为另一种数据类型的过程。C# 是一种静态类型语言,因此了解如何正确地在类型之间进行转换至关重要。转换主要分为两类:隐式转换和显式转换。

隐式转换由 C# 编译器自动执行,当转换类型安全且不会丢失数据时。这通常发生在将较小、精度较低的类型转换为较大、精度较高的类型时(例如,int 到 double)。

这里,一个 int 被隐式安全地转换为 long 和 double。

using System;
class ImplicitConversionExample {
static void Main() {
int myInt = 12345;
Console.WriteLine($"原始 int: {myInt}");
// 隐式将 int 转换为 long(安全,无数据丢失)
long myLong = myInt;
Console.WriteLine($"隐式转换为 long: {myLong}");
// 隐式将 int 转换为 double(安全,无数据丢失)
double myDouble = myInt;
Console.WriteLine($"隐式转换为 double: {myDouble}");
}
}

编译并执行上述代码后,它会产生:

Original int: 12345
Implicitly converted to long: 12345
Implicitly converted to double: 12345

显式类型转换(窄化转换 / 强制转换)

Section titled “显式类型转换(窄化转换 / 强制转换)”

显式转换需要强制转换运算符 (),并用于存在数据丢失风险或转换不明显安全的情况。这通常发生在将较大类型转换为较小类型时(例如,double 到 int)。您是在告诉编译器:“我知道这可能会丢失信息,但我仍然想这样做。”

此示例显示将 double 转换为 int。小数部分被截断(而不是四舍五入)。

using System;
class ExplicitConversionExample {
static void Main() {
double myDouble = 9876.54;
Console.WriteLine($"原始 double: {myDouble}");
// 显式将 double 强制转换为 int。小数部分丢失。
int myInt = (int)myDouble;
Console.WriteLine($"显式强制转换为 int: {myInt}");
// 另一个更大的值不适合的示例
double largeDouble = 3000000000.0;
// 如果不小心处理,这会导致溢出。
// 在未检查的上下文中,行为可能是不可预测的。
int overflowInt = (int)largeDouble;
Console.WriteLine($"将大 double 强制转换为 int (溢出): {overflowInt}");
}
}

执行后,此代码会产生:

Original double: 9876.54
Explicitly cast to int: 9876
Casting a large double to int (overflow): -1294967296

警告: 显式数值强制转换可能因数据丢失或溢出而导致意外结果。始终确保目标类型可以容纳源值。

C# 提供了内置的辅助方法,用于更受控和更健壮的类型转换,尤其是在处理字符串时。

System.Convert 类提供了一套全面的方法,用于在基本类型之间进行转换。与强制转换不同,它可以处理更广泛的转换(例如,string 到 int),并在将浮点数转换为整数时执行四舍五入。

using System;
class ConvertClassExample {
static void Main() {
double myDouble = 98.76;
string boolString = "true";
// Convert.ToInt32 将 double 四舍五入到最接近的整数
int roundedInt = Convert.ToInt32(myDouble);
Console.WriteLine($"Convert.ToInt32({myDouble}) = {roundedInt}");
// 将字符串转换为布尔值
bool myBool = Convert.ToBoolean(boolString);
Console.WriteLine($"Convert.ToBoolean(\"{boolString}\") = {myBool}");
// 如果字符串不是有效的数字,这将抛出 FormatException
try {
int num = Convert.ToInt32("not a number");
} catch (FormatException e) {
Console.WriteLine($"错误: {e.Message}");
}
}
}

数值类型(如 int、double 等)具有用于转换字符串的静态 Parse() 和 TryParse() 方法。

  • Parse(): 将字符串转换为其对应的类型。如果转换失败(例如,字符串不是有效的数字),它会抛出 FormatException。
  • TryParse(): (推荐最佳实践) 尝试转换字符串并返回一个 bool 值,指示转换是否成功。它在失败时不会抛出异常,使其成为处理用户输入或潜在无效数据的一种更安全、更高效的方法。
using System;
class TryParseExample {
static void Main() {
string userInput = "123";
if (int.TryParse(userInput, out int parsedNumber)) {
// 转换成功
Console.WriteLine($"成功将 '{userInput}' 解析为 {parsedNumber}。");
} else {
// 转换失败
Console.WriteLine($"未能解析 '{userInput}'。");
}
string invalidInput = "hello";
if (int.TryParse(invalidInput, out int failedParseResult)) {
Console.WriteLine($"成功将 '{invalidInput}' 解析为 {failedParseResult}。");
} else {
Console.WriteLine($"未能解析 '{invalidInput}'。它不是一个有效的整数。");
}
}
}

这将产生以下安全输出:

Successfully parsed '123' to 123.
Failed to parse 'hello'. It's not a valid integer.
方法何时使用关键行为
隐式转换当转换为不会丢失数据的更大/更宽类型时(例如,int 到 double)。自动,无需语法。
显式强制转换 (type)当转换为较小/较窄类型且您知道可能存在数据丢失时。截断数据。可能导致溢出。快速。
Convert.To...()用于基本类型之间的通用转换。适用于在不同数字类型之间转换。四舍五入数字。失败时抛出异常。
TryParse()最佳实践,用于将字符串转换为其他类型,特别是来自用户输入或外部源时。返回 bool,不抛出异常。安全高效。
Parse()当转换字符串且您确定它有效时。如果无效,则接受抛出异常。失败时抛出异常。