在C#中,有且仅有两种数据类型:值类型和引用类型。换言之,一个变量要么是值类型,要么是引用类型。像我们常见的数据类型(int,float,double)、结构、枚举等等都属于值类型,而像类、接口、委托等都属于引用类型。所以,要想深入的了解.net framework的一些原理性的知识,值类型与引用类型是跨不过去的一道门槛。
下面是一个关于C#中的类型的总结图片
但是C#中的基本类型的定义是源于什么呢:
C#中变量的类型取决于什么?
在C#中,变量是值类型还是引用类型,取决于其基本数据类型。在C#中,其基本数据类型并没有内置于语言中,而是存在与.Net Framewok中。.Net使用CTS(通用语言系统)定义在IL(中间语言)中使用的预定义数据类型。C#中所有数据类型都是对象,它们有属性、方法等。
例如,在C#中声明一个int变量时,实际上是声明了CTS中System.Int32的一个实例。
值类型
前面已经说过,值类型隐式派生于System.ValueType,那么在平时遇到的数据类型中,有哪些属于值类型呢?
整型。包括我们常见的short、int、long、byte、sbyte、bigint等这。
浮点型。包括float、double。
用于财务计算的高精度decimal类型。
结构体。struct,已经预定好的和用户自定义的。
枚举。
bool类型。
可空类型。
每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,这也是为什么像定义一个int型的变量时,有时候没有初始化,它也会有初始值为0的缘故。
还有一点需要注意的是,所有值类型都是seal(密封)类型,是不能再派生出新的数据类型的。
引用类型
在C#中,有以下这些引用类型:
数组。
类。
接口。
委托。
object。其实就是System.Object,老大哥。
字符串。string,System.String的别名,这也是一个极其重要的引用类型,后面会有专门一篇来描述字符串中的点点滴滴。
与值类型不同的是,引用类型可以派生出新的类型(不绝对话,比如说string就不可以)。需要注意的是,值类型中的结构体也是可以实现接口的。
内存分配
说起值类型和引用类型的不同,内存分配可谓是它们的本质区别了,这也可以让我们更加清晰的了解一些生活中遇到的问题。
值类型的实例一般都会存放在栈上,之所以说是一般,是因为它有时候也会去引用类型那里窜门,会有特殊情况,存放在堆上,接下来会讲。与之不同的是,引用类型的对象则总是存储在堆中,当然它的引用有时候也会存放在栈上,但是对象实例是一定存放在堆上的。