这篇文章主要介绍了C#类型系统有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
我们先简单回顾一下C#类型系统。C#类型系统一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)。值类型 和引用类型是以它们在计算机内存中是如何被分配的来划分的。值类型包括 结构和枚举,引用类型包括类、接口、委托等。还有一种特殊的值类型,称为简单类型(Simple Type),比如 byte,int等,这些简单类型实际上是FCL类库类型的别名,比如声明一个int类型,实际上是声明一个System.Int32结构类型。因此,在 Int32类型中定义的操作,都可以应用在int类型上,比如 “123.Equals(2)”。
所有的 值类型 都隐式地继承自 System.ValueType类型(注意System.ValueType本身是一个类类型),System.ValueType和所有的引用类型都继承自 System.Object基类。你不能显示地让结构继承一个类,因为C#不支持多重继承,而结构已经隐式继承自ValueType。
1.值类型
当声明一个值类型的变量(Variable)的时候,变量本身包含了值类型的全部字段,该变量会被分配在线程堆栈(Thread Stack)上。假如我们有这样一个值类型,它代表了直线上的一点:
public struct ValPoint { public int x; public ValPoint(int x) { this.x = x; } }
2.引用类型
当声明一个引用类型变量的时候,该引用类型的变量会被分配到堆栈上,这个变量将用于保存位于堆上的该引用类型的实例的内存地址,变量本身不包含对象的数据。此时,如果仅仅声明这样一个变量,由于在堆上还没有创建类型的实例,因此,变量值为null,意思是不指向任何类型实例(堆上的对象)。对于变量的类型声明,用于限制此变量可以保存的类型。
如果我们有一个这样的类,它依然代表直线上的一点:
public class RefPoint { public int x; public RefPoint(int x) { this.x = x; } public RefPoint() {} }
3.关于简单类型
很多文章和书籍中在讲述这类问题的时候,总是喜欢用一个int类型作为值类型 和一个Object类型作为引用类型来作说明。本文中将采用自定义的一个 结构 和 类分别作值类型和引用类型的说明。这是因为简单类型(比如int)有一些CLR实现了的行为,这些行为会让我们对一些操作产生误解。
举个例子,如果我们想比较两个int类型是否相等,我们会通常这样:
int i = 3; int j = 3; if(i==j) Console.WriteLine("i equals to j");
实际上,在后面我们就会看到,当使用“==”对引用类型变量进行比较的时候,比较的是它们是否指向的堆上同一个对象。而上面a、b指向的显然是不同的对象,只是对象包含的值相同,所以可见,对于string类型,CLR对它们的比较实际上比较的是值,而不是引用。
为了避免上面这些引起的混淆,在对象判等部分将采用自定义的结构和类来分别说明。
装箱和拆箱
这部分内容可深可浅,本文只简要地作一个回顾。简单来说,装箱 就是 将一个值类型转换成等值的引用类型。它的过程分为这样几步:
1. 在堆上为新生成的对象(该对象包含数据,对象本身没有名称)分配内存。
2. 将 堆栈上 值类型变量的值拷贝到 堆上的对象 中。
3. 将堆上创建的对象的地址返回给引用类型变量(从程序员角度看,这个变量的名称就好像堆上对象的名称一样)。
感谢你能够认真阅读完这篇文章,希望小编分享的“C#类型系统有哪些”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/tech/dev/230565.html