从C#的ValueType引发的思考

无论上层语言类型多么复杂,在.NET平台上,都逃不过CTS的约束,今天,我想说的不是CTS,而是上层语言C#类型的一点研究。

请看一下下面的这个代码段:

1     public struct test
2     {
3         public override bool Equals(object obj)
4         {
5             return base.Equals(obj);
6         }
7     }

这是我随便定义的一个结构,可以看到这个结构什么都没有继承,但是我却可以重写出Equals方法,这个方法来自哪里,这个结构的父亲又是谁呢?

一、结构为什么不能继承类

开门见山,ValueType!!

是的,所有的结构都默认继承了该类,对的,是一个类,也就是说所有的结构都是有继承的,继承了ValueType,也是因为这样,所以结构不能再继承类了,只能继承接口,因为C#是单继承的。

二、为什么每个结构都有ToString等方法

ValueType!还是ValueType!

因为结构默认继承了ValueType,也就是继承了Object,所以其实结构可以看成一个类,只是这个类很特别,比静态类,最终类还特别,区别包括:编译时会对他进行特殊处理,内存分配规则,不能被继承,实例化过程等等。所以结构在写法上和类很多地方很像,比如也可以拥有方法,等等,其实结构就是一个被阉割的非常厉害的类。

三、enum的类型

enum也是值类型,为什么这么说呢?

1、typeof(枚举).BaseType可以看到enum的付类是System.Enum类,而System.Enum继承ValueType。

2、enum的内存分配方式和值类型一样都是分配在栈上。

3、enum是一种特殊的值类型,不能有结构,函数等等。

但是System.Enum是类(引用类型),所以并不是所有继承ValueType的都是值类型(这个类我们自己也可以写个类去继承)

四、哪些类型是值类型?值类型有什么特点?

1、基础类型:decimal、bool、char、byte、sbyte、short、int、long、ushort、uint、ulong、single、double

2、用户自定义值类型(以关键字struct声明的)

3、enum特殊值类型

值类型特点:值类型的数据特点很多,大多是和类做区分的,具体大家可以查一下资料哈。

五、值类型可以继承接口,用接口访问值类型的时候,是值还是引用?

大家猜一猜是值还是引用呢?好了先公布答案吧,答案是引用!

IComparable i = 0; 当用接口指向值得时候,这个值会有一个装箱得过程,也就是值类型会装箱成一个引用类型。下面,我们用以下代码段来证明一下。

 1 //结构体班级   
 2 struct StructClass : IClass 
 3 {   
 4     public int Count;//人数   
 5     public void AddStudent()
 6     {   
 7         Count++;   
 8     }   
 9   
10     public void ShowCount()
11     {   
12         Console.WriteLine(Count);   
13     }   
14   
15 }   
16 //接口   
17 interface IClass
18 {   
19     void AddStudent();//添加学生   
20     void ShowCount();//显示学生人数   
21 }   
22 class Program
23 {   
24     static void Main(string[] args) 
25     {   
26         StructClass s1 = new StructClass();   
27         StructClass s2 = s1;   
28         s1.AddStudent();   
29         s1.ShowCount(); //输出1   
30         s2.ShowCount(); //输出0   
31         //说明s2和s1不指向同一个对象,s2=s1是创建了一个s1的副本   
32         //这是值类型很显著的标志   
33   
34         IClass ic1 = new StructClass();   
35         IClass ic2 = ic1;   
36         ic1.AddStudent();   
37         ic1.ShowCount();//输出1   
38         ic2.ShowCount();//输出1   
39         //说明s2和s1指向同一个对象,s2=s1是将s1的引用赋给s2   
40         //这是引用类型很显著的标志   
41     }   
42 }  

完毕!

posted @ 2020-03-02 14:13  萌萌丶小魔王  阅读(2020)  评论(2编辑  收藏  举报