从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 }  

完毕!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM