基元类型
基元类型是编译器直接支持的数据类型,基元类型直接映射到Framework类库(FCL)中存在的类型。例如int 映射到System.Int32 。
下表列出了常见的基元类型与对应的FCL类型。
c#基元类型 | FCL类型 | 说明 |
---|---|---|
sbyte | System.SByte | 有符号8位值 |
byte | System.Byte | 无符号8位值 |
short | System.Int16 | 有符号16位值 |
ushort | System.UInt16 | 无符号16位值 |
int | System.Int32 | 有符号32位值 |
uint | System.UInt32 | 无符号32位值 |
long | System.Int64 | 有符号64位 |
ulong | System.UInt64 | 无符号64位值 |
char | System.Char | 16位Unicode字符 |
float | System.Single | IEEE 32位浮点值 |
double | System.Double | IEEE 64位浮点值 |
bool | System.Boolean | true/flase |
string | System.String | 字符数组 |
object | System.Object | 所有类型的基类型 |
dynamic | System.Object | … |
基元类型的许多操作都可能造成溢出,如下:
byte b = 100;
// result of the expression is 44
b = (byte) (b + 200)
-
以上代码注意两点
- 加上200之后做类型转换,是因为 byte 类型实际运算的时候会被转换为 int 类型。
- 此处发生了溢出,但运行时不会报错。
一般使用关键字 checked 和 unchecked 来指定是否做溢出判断。如下,加上 checked关键字之后,若发生溢出,以下代码将抛出OverflowException 的异常。
byte b = 100;
// result of the expression is 44
b = checked((byte) (b + 200))
引用类型和值类型
引用类型在托管堆上分配内存,值类型在线程栈上分配内存。值类型的使用缓解了托管堆的压力,所有值类型都从System.Object 派生。
System.Object -> System.ValueType -> System.Enum
值类型的装箱是将值复制到托管堆上,返回引用地址的过程,拆箱相反。
以下代码示例很好的解释了这个过程。
using System;
internal struct Point
{
private int x, y;
// constructor
public Point(int x1, int y1)
{
x = x1;
y = y1;
}
// change the value of x and y
public void Change(int x1, int y1)
{
x = x1;
y = y1;
}
// override ToString()
public override String ToString()
{
return String.Format("({0}, {1})", x.ToString(), y.ToString());
}
}
public sealed class Program
{
public static void Main()
{
// new point
Point p = new Point(1, 1);
// boxing up the struct p by copying its x and y to the heap
Console.WriteLine(p);
// operation on struct p (value type)
p.Change(2, 2);
// boxing again, copy the changed value
Console.WriteLine(p);
// boxing up the struct with explicit operation
Object o = p;
// no need to boxing up
Console.WriteLine(o);
// unboxing the reference type
((Point) o).Change(3, 3);
// changes happend to the unboxed value on stack,
// o is on heap, remain unchanged
Console.WriteLine(o);
}
}
运行结果如下: