C# 和许多静态类型语言一样,提供了多种表示整数的类型,每种都有自己的取值范围。在低端,sbyte类型的最小值为 -128,最大值为 127。和所有的整数类型一样,这些值都可以通过 <type>.MinValue和<type>.MaxValue 获取。在高端,long类型的最小值为 -9,223,372,036,854,775,808,最大值为 9,223,372,036,854,775,807。介于两者之间的是 short和int类型。
上述每个类型都有一个对应的无符号版本:sbyte/byte、short/ushort、int/uint和long/ulong。在所有情况下,取值范围都是从 0 到有符号最大值的负数乘以 2 再加 1。
无符号整数类型的值使用简单的二进制表示。有符号类型的值则使用补码表示。
整数类型如此之多,反映的是机器架构的差异:寄存器的大小、CPU 指令参数的大小,以及 CPU 内部对符号的处理方式。long类型的值使用 64 位,而 sbyte类型的值使用 8 位。在某些情况下,这会影响到 CPU 性能、内存占用,甚至磁盘占用(选择较小的整数类型通常更有利)。选择整数type也可以作为一种粗略的方式,向其他开发者传达预期取值范围的信息。在特定用途没有特殊要求时,int类型被广泛用作默认类型。long或ulong则常被用作简单的标识符。类型的大小(以字节为单位)决定了取值范围。
到目前为止讨论的类型都是_基元_类型。每个类型都对应一个 struct 别名,它实现了与该类型相关联的字段(例如 MinValue)和方法(例如 ToString())。
| 类型 | 结构体 | 宽度 | 最小值 | 最大值 |
|---|---|---|---|---|
sbyte |
SByte |
8 bit | -128 | +127 |
short |
Int16 |
16 bit | -32_768 | +32_767 |
int |
Int32 |
32 bit | -2_147_483_648 | +2_147_483_647 |
long |
Int64 |
64 bit | -9_223_372_036_854_775_808 | +9_223_372_036_854_775_807 |
byte |
Byte |
8 bit | 0 | +255 |
ushort |
UInt16 |
16 bit | 0 | +65_535 |
uint |
UInt32 |
32 bit | 0 | +4_294_967_295 |
ulong |
UInt64 |
64 bit | 0 | +18_446_744_073_709_551_615 |
一种类型的变量(或表达式)可以很方便地转换为另一种类型。例如,在赋值操作中,如果被赋值的值(右侧)的类型能够保证该值落在赋值目标(左侧)类型的范围内,那么就是一次简单的赋值:
ulong ul;
uint ui = uint.MaxValue;
ul = ui; // no problem
另一方面,如果来源类型的取值范围不是赋值目标取值范围的子集,那么即使具体的值落在目标类型的范围内,也需要进行强制转换,即()运算:
uint ui;
short s = 42;
ui = (uint)s;
在上面的例子中,如果该值反而超出了赋值目标的取值范围,就会发生溢出。参见 overflow。
是否需要进行类型转换,取决于涉及的这两种类型,而不是某个具体的值。
接下来的几段讨论整数类型的强制转换。(参见 casting,其中更广泛地讨论了强制转换和类型转换。)关于整数类型与浮点数、char和bool之间的转换,请参阅该文档。
C# 的类型系统比 C 或 Javascript 更严格一些,因此类型转换操作也受到更多限制。只要“目标”类型能够保留“来源”类型的值的量级和符号,隐式转换就会发生在两个数值类型之间。
隐式转换不需要任何特殊的语法来表示。
当数值类型无法隐式转换时,通常可以使用显式转换运算符。
如果被转换的值因为宽度不够或符号冲突而无法用“目标”类型表示,就可能抛出溢出异常。
int largeInt = Int32.MaxValue;
int largeNegInt = Int32.MinValue;
ushort shortUnsignedInt = ushort.MaxValue;
// implicit cast
int from_ushort = shortUnsignedInt; // 65535
float from_int = largeInt; // -21474836E+09
// explicit cast
uint from_largeInt = (uint)largeInt; // 2147483647
uint from_neg = (uint) largeNegInt; // 2147483648 or OverflowException is thrown (if checked)
BitConverter 类提供了一种便捷的方式,在整数类型和字节数组之间相互转换。