第 6 节 · 第一部分 基础语法

类型转换

放得下就自动转(隐式),放不下要亲手写括号(显式,可能丢数据),字符串要“读”出来才是数(Convert / Parse / TryParse)。

时长 8:06授课计划第 2 周

学完这一节,你能

讲义

跟着视频的顺序写。每行代码都有注释,代码和运行结果都是实际运行得到的。

1类型转换是什么

上一节留的问题:3.5 非要放进 int 怎么办?在前面加一对括号写上 int,结果是 3。下面的例子多数是顶级语句写法(不写类和 Main,代码从第一行开始执行)。

C# · 第 1-2 行
1int n = (int)3.5;// (int) 把 3.5 转成 int,小数部分去掉,n = 3
2Console.WriteLine(n);// 输出 3

把一个类型的值变成另一个类型,就叫类型转换。C# 的类型转换分两种:隐式转换和显式转换。

2隐式转换

不用写任何代码,编译器(把代码翻译成程序的工具)自动帮你转,条件是从小范围转到大范围。byte 只占 1 个字节,int 占 4 个字节,10 从小的放进大的,一点不丢。

C# · 第 1-3 行
1byte b = 10;// byte 变量 b,值是 10
2int i = b; // 隐式转换,不需要显式转换// 直接把 byte 赋给 int,编译器自动转
3Console.WriteLine(i);// 输出 10

同理,int 能直接放进 long,float 能直接放进 double,运行结果 42 和 1.5 原样不变。反过来,把 int 直接放进 byte,编译器不答应:

C# · 第 1-2 行
1int i = 10;// int 变量 i,值是 10
2byte b = i;// 大范围的 int 直接放进小范围的 byte
编译报错
Program.cs(2,10): error CS0266: 无法将类型“int”隐式转换为“byte”。存在一个显式转换(是否缺少强制转换?)

教程还提到,派生类转基类也是隐式转换,讲继承时再说。

3显式转换

显式转换也叫强制类型转换:在值前面加一对括号,括号里写目标类型。

C# · 第 2-3 行
2byte b = (byte)i; // 显式转换,需要使用强制类型转换符号// i 是 10,(byte) 把它转成 byte
3Console.WriteLine(b);// 输出 10

溢出

强制转换是可能丢数据,不是一定丢:10 放得下就一点不丢。可 byte 最大只到 255,300 比 256 多出 44,数值绕回起点只剩 44,这叫溢出。

C# · 第 2-3 行
2byte b = (byte)i;// i 是 300,强制转成 byte:300 - 256 = 44
3Console.WriteLine(b);// 输出 44

截断

double 转 int,小数部分被直接去掉,这叫截断,不是四舍五入,和溢出是两回事。

C# · 第 1-4 行
1double doubleValue = 3.14;// double 变量,整数部分 3,小数部分 0.14
2int intValue = (int)doubleValue; // 强制从 double 到 int,数据可能损失小数部分// 去掉 0.14,只剩 3
3Console.WriteLine(intValue);// 输出 3
4Console.WriteLine((int)3.99);// 3.99 也是去掉小数,输出 3,不是 4

教程里的完整例子把 5673.74 强制转成 int,输出 5673,小数部分没了。

int 转 float

int 转 float 允许隐式转换,不写 (float) 也行(实测 42 转完还是 42)。但 float 只能精确存 7 位左右的数字,大整数会丢精度:

C# · 第 1-3 行
1int big = 16777217;// 一个 8 位数
2float f = big;// 不写括号,int 自动转成 float
3Console.WriteLine(f);// 输出 16777216,最后一位变了

转成字符串

数字变字符串不能用强制转换,写成 (string)123 编译报错 CS0030(无法将类型“int”转换为“string”),要调用 ToString() 方法:

C# · 第 2-3 行
2string stringValue = intValue.ToString(); // 将 int 转换为字符串// intValue 是 int 123,变成字符串 "123"
3Console.WriteLine(stringValue + "4");// 字符串 + 字符串是接起来,输出 1234,不是 127

4Convert 类

除了括号,C# 在 System 命名空间(存放一组类的“文件夹”)的 Convert 类里准备了一整套转换方法,名字都是 To 加类型名,用的是正式类型名:Int32 就是 int,Single 就是 float。教程列的 16 个都真跑过:

查看完整代码(16 行)
C#
1Console.WriteLine(Convert.ToBoolean("true"));// 转成 bool,输出 True
2Console.WriteLine(Convert.ToByte("255"));// 转成 byte,输出 255
3Console.WriteLine(Convert.ToChar(65));// 65 转成字符,输出 A
4Console.WriteLine(Convert.ToDateTime("2026-10-28").ToString("yyyy-MM-dd"));// 转成日期类型 DateTime,按年-月-日打印 2026-10-28
5Console.WriteLine(Convert.ToDecimal(0.1));// 转成 decimal,输出 0.1
6Console.WriteLine(Convert.ToDouble("2.5"));// 转成 double,输出 2.5
7Console.WriteLine(Convert.ToInt16("-300"));// 转成 short,输出 -300
8Console.WriteLine(Convert.ToInt32("123"));// 转成 int,输出 123
9Console.WriteLine(Convert.ToInt64("9000000000"));// 转成 long,输出 9000000000
10Console.WriteLine(Convert.ToSByte("-5"));// 转成 sbyte(带符号的 byte),输出 -5
11Console.WriteLine(Convert.ToSingle("1.25"));// 转成 float,输出 1.25
12Console.WriteLine(Convert.ToString(42) + "!");// 转成 string 再接上 "!",输出 42!
13Console.WriteLine(Convert.ChangeType("7", typeof(int)));// ChangeType:转成 typeof(int) 取到的 int 类型,输出 7
14Console.WriteLine(Convert.ToUInt16("65535"));// 转成 ushort,输出 65535
15Console.WriteLine(Convert.ToUInt32("4000000000"));// 转成 uint,输出 4000000000
16Console.WriteLine(Convert.ToUInt64("18000000000000000000"));// 转成 ulong,输出 18000000000000000000

方法表要改正的地方

  1. 方法名是 ToSByte(b 大写),没有 ToSbyte;也没有 ToType,想转成指定类型用 ChangeType。
C# · 第 1-2 行
1sbyte s = Convert.ToSbyte("-5");// b 写成小写
2int n = Convert.ToType("7");// Convert 里没有 ToType
编译报错
Program.cs(1,19): error CS0117: “Convert”未包含“ToSbyte”的定义
Program.cs(2,17): error CS0117: “Convert”未包含“ToType”的定义
  1. ToDateTime 能转日期字符串,但不能转整数:Convert.ToDateTime(20261028) 会抛出 InvalidCastException。

Convert 和括号不一样

字符串 "123" 转成整数后再加 1 得 124,确实是数字了;字符串是 null(空,什么都没有)时,结果是 0。

C# · 第 2-3 行
2int number = Convert.ToInt32(str); // 转换成功,number为123// str 是 "123"
3Console.WriteLine(number + 1);// 数字相加:123 + 1,输出 124

字符串是 abc,就抛出 FormatException(异常就是运行时出的错,这个表示格式不对),程序到这里就停了:

C# · 第 1-2 行
1string str = "abc";// 不是数字的字符串
2int number = Convert.ToInt32(str);// 读不成整数,抛出异常
查看完整输出(4 行)
运行结果
Unhandled exception. System.FormatException: The input string 'abc' was not in a correct format.
   at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)
   at System.Convert.ToInt32(String value)
   at Program.<Main>$(String[] args) in 类型转换/c-abc/Program.cs:line 2

300 用括号转 byte 得 44,用 Convert.ToByte(300) 却抛出 OverflowException:装不下就报出来,不悄悄变成别的数,这就是说它安全的意思。小数转整数时,Convert 取最接近的整数:

C# · 第 1-2 行
1Console.WriteLine((int)3.7);// 括号:截断小数,输出 3
2Console.WriteLine(Convert.ToInt32(3.7));// Convert:取最接近的整数,输出 4

5ToString 实例

教程定义了 int、float、double、bool 四个变量,再用 ToString() 逐个转成字符串打印,bool 打印出来是首字母大写的 True。

运行结果
75
53.005
2345.7652
True

6注意事项

  1. 隐式转换只能从小范围到大范围,反过来不行。
  2. 显式转换可能丢数据、丢精度,转之前要想清楚放不放得下。
  3. 对象类型之间转换,要先检查能不能转、安不安全,这一条等讲类的时候再展开。

7Convert、Parse 和 TryParse

这三种方法最常用来把字符串变成数字。double.Parse 用法和 Convert 差不多;字符串要不是数字,也会抛出 FormatException,程序停下。

C# · 第 1-3 行
1string str = "123.45";// 写着数字的字符串
2double d = double.Parse(str);// Parse:把字符串解析成 double
3Console.WriteLine(d);// 输出 123.45

TryParse 不会让程序停下:成功返回 true,转出来的数从 out 参数(方法通过它把结果交回来)那里拿,所以后面配一个 if。下面 str 是 "123.45",d 是前面声明的 double 变量。

C# · 第 3-9 行
3bool success = double.TryParse(str, out d);// 试着转换:成功返回 true,结果放进 d
4
5if (success) {// 成功了(if 开始)
6 Console.WriteLine("转换成功: " + d);// 输出 转换成功: 123.45
7} else {// 没成功(else 开始)
8 Console.WriteLine("转换失败");// str 换成 "abc" 时走这里,输出 转换失败
9}// if-else 结束

用户输入的东西不一定是数字,这时用 TryParse 最稳。

8自定义类型转换

C# 允许给自己写的类型定义转换,用到 implicit(隐式)或 explicit(显式)关键字和 operator(定义运算或转换的写法,后面会讲)。教程的例子是华氏温度类 Fahrenheit,度数存在属性 Degrees 里(类和属性后面会讲)。

C# · 第 13-21 行
13public static implicit operator double(Fahrenheit f)// 规定 Fahrenheit 可以自动转成 double
14{// 转 double 的 operator 开始
15 return f.Degrees;// 转出来的就是度数
16}// 转 double 的 operator 结束
17
18// 显式转换从double到Fahrenheit
19public static explicit operator Fahrenheit(double d)// 规定 double 转回 Fahrenheit 必须写括号
20{// 转 Fahrenheit 的 operator 开始
21 return new Fahrenheit(d);// 用这个度数新建一个 Fahrenheit 对象
C# · 第 32-35 行
32double temp = f; // 隐式转换// f 是度数 98.6 的 Fahrenheit 对象,自动转成 double
33Console.WriteLine("After implicit conversion to double: " + temp + " degrees");// 输出 98.6
34
35Fahrenheit newF = (Fahrenheit)temp; // 显式转换// 写括号把 double 转回 Fahrenheit

运行出三行,都是 98.6 度:转过去又转回来,值没变。要是转回来时漏写 (Fahrenheit),报的错和内置类型一样是 CS0266。类和 operator 的细节,后面讲类的时候再说。

9小结

  • 隐式转换自动发生,用于安全的转换;显式转换要写括号,可能丢数据(溢出、截断)。
  • Convert 类有一整套 To 方法,装不下会报异常,小数取最接近的整数。
  • Parse 把字符串解析成各种类型,失败抛异常;TryParse 用返回值告诉你成没成功。
  • Boolean、Int16、Int32 就是 bool、short、int 的正式名字。
  • 一句话:放得下就自动转,放不下要亲手写括号,字符串得读出来才是数。

下一节:转换讲完了,这些值总得有个地方放——变量怎么声明、怎么起名、怎么赋初值?

检查题

5 道,选完马上告诉你对不对。

  1. 1int i = 10; byte b = i; 会怎样?

  2. 2(int)3.99 的结果?

  3. 3int i = 300; byte b = (byte)i; 输出?

  4. 4用户输入的字符串可能不是数字,想不让程序停下,用哪个?

  5. 5教程表里的 ToType 方法: