C#有两种类型:值类型和引用类型。值类型的变量直接包含数据,而引用类型的变量则存储对数据(称为“对象”)的引用。对于引用类型,两个变量可以引用同一对象;因此,对一个变量执行的运算可能会影响到另一个变量引用的对象。借助值类型,每个变量都有自己的数据副本;因此,对一个变量执行的运算不会影响另一个变量(ref和out参数变量除外)。
C#类型又细分为简单类型、枚举类型、结构类型和可以为null的值类型。C#引用类型又细分为类类型、接口类型、数组类型和委托类型。
下面概述了C#的类型系统。
有符号的整型:sbyte、short、int、long
无符号的整型:byte、ushort、uint、ulong
Unicode字符:char
IEEE二进制浮点:float、double
高精度十进制浮点数:decimal
布尔:bool
格式为 enum E{ ...}的用户定义类型
格式为 struct S{ ...的与用户定义类型
值为null的其他所有值类型的扩展
其他所有类型的最终基类:object
Unicode字符串:string
格式为 class C{...}的用户定义类型
格式为interface I{...}的用户定义类型
一维和多维,例如int [ ]和int [ , ]
格式为delegate int D(...)的用户定义类型
C#的bool类型用于表示布尔值(true或flase)。
C#使用Unicode编码处理字符和字符串。char类型便是UTF-16代码单元,string类型表示一系列UTF-16代码单元。
C#程序使用类型声明创建新类型。类型声明指定新类型的名称和成员。用户可定义一下五种C#类型:类类型、结构类型、接口类型、枚举类型和委托类型。
class类型定义包含数据成员(字段)和函数成员(方法、属性及其他)的数据结构。类类型支持单一继承和多形性,即派生类可以扩展和专门针对基类的机制。
struct类型定义包含数据成员和函数成员的结构,这一点与类类型类似。不过,与类不同的是,结构是值类型,通常不需要进行堆分配。结构类型不支持用户指定的继承,并且所有结构类型均隐式继承自类型object。
delegate类型表示引用包含特定参数列表和返回类型的方法。通过委托,可以将方法视为可分配给变量并可作为参数传递的实体。委托类同于函数式语言提供的函数类型。委托也类似于其他一些语言中的函数指针概念,但是与函数指针不同的是,委托不仅面向对象,还类型安全。
interface类型将协定定义一组已命名的公共函数成员。实现interface的class或struct必须提供接口函数成员的实现代码。interface可以继承自多个基接口,class和struct可以实现多个接口。
class、struct、interface和delegate类型全部都支持泛型,因此可以使用其他类型对他们进行参数化。
enum类型是一种包含已命名常量的独特类型。每个enum类型都有一个基础类型(必须是八种整型类型之一)。enum类型的值集与基础类型的值集相同。
C#支持任意类型的一维数组和多维数组。与上述类型不同,数组无需先声明即可使用。相反,数组类型是通过在类型名称后面添加方括号构造而成。例如,int[ ]是int类型的一维数组,int [ ]是int类型的二维数组,int[ ] [ ]是由int类型的一维数组构成的一维数组。
可以为null的值类型也可以无需先声明即可使用。对于所有不可以为null的值类型T,都有对应的可以为null的值类型T?,后者可以包含附加值null 例如,int?是可以包含任何32位整数或值null的类型。
C#采用统一的类型系统,因此任意类型的值都可以视为object。每种C#类型都直接或间接地派生自object类类型。而object是所有类型的最终基类。只需将值视为类型object,即可将引用类型的值视为对象。通过执行装箱和取消装箱操作,可以将值类型的值视为对象。在以下示例中,int值被转换成object,然后又恢复成int。
using System;
class BoxingExample
{
static void Main()
{
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}
当值类型的值转换成object类型时,将分配obje实例(亦称为"箱")来包含值,然后该值会赋值到相应的箱中。相反,当obje引用被显式转换成值类型时,将检查引用的object是否具有正确值类型的箱;如果检查成功,则会将箱中的赋值出来。
C#的统一类型系统实际上意味着可以“按需”将值类型转换成对象。鉴于这种统一性,使用类型object的常规用途库可以与引用类型和值类型结合使用。
C#有多种变量,其中包括字段、数组元素、局部变量和参数。变量表示存储位置,每个变量都具有一种类型,用于确定可以在变量中存储哪些值,如下文所述。
不可以为null的值类型:具有精确类型的值
可以为null的值类型:null值或具有精确类型的值
类类型:null引用,对类类型实例的引用,或对派生自类类型的装箱值的引用
Object:null引用、对任意引用类型的对象的引用,或对任意值类型的装箱值得引用
接口类型:null引用,对实现接口类型得类类型实例的引用,或对实现接口类型的值类型的装箱值得引用
数组类型:null引用、对数组类型实例得引用,或对兼容得数组实例的引用
委托类型:null引用或对兼容的委托类型实例的引用