首页 新闻 赞助 找找看

struct与class继承的问题

0
悬赏园豆:50 [已解决问题] 解决于 2012-04-27 22:10

值类型继承于System.ValueType,而System.ValueType是类,而System.Int32却是struct,struct是不能继承于类,如何解释?

alab的主页 alab | 初学一级 | 园豆:19
提问于:2012-04-27 21:56
< >
分享
最佳答案
0
在C#中,相信大家对于 "值类型" 并不陌生,因为它在我们代码设计中是不可缺少的,那么究竟什么是 "值类型" 呢? "值类型" 就是 我们用到的 Int16,Int32这些数值类型吗?

  我们知道在C#中所有的类型继承于System.Object根类型,这也就意味着就代码层面来讲,在C#中所有的类型都是Class,,即一切都是Class类型,既然全部都是Class类型,那么值类型在哪里呢?我们可以发现在C#中System.Int16,System.Int32,System.Boolean...等等这些常用的类型都是Struct 结构类型,那么结构类型是什么,下面我们定义一个结构,然后通过IL Disassemble 工具来查看编译的中间代码便可以得到结果.

  public struct CustomerStruct

  {

  public string Name{get;set;}

  }

  代码非常简单,我们就定义一个struct类型,并且包含一个Name属性.

C#

  看到上面这幅图,相信大家都已经看到定义一个struct类型实际上编译把你所定义的类型继承了System.ValueType类型,换句话说,在C#中我们经常使用的System.Int16,System.Int32,System.Boolean..这些数值结构类型都是继承于System.ValueType类型,而System.ValueType又是继承于System.Object根类型,即验证我开始所讲到的在C#中一切类型都是Class。

  之所以存在"值类型" 这个概念,其实是因为C#中的某些类型有这特殊的地位(即继承于System.ValueType的类型),CLR会特殊的对待这些类型,

  看下面这2行代码

  Int32 a = new System.Int32(10) ;

  CustomerStruct customer = new CustomerStruct() ;

  首先为什么对于数值类型也可以使用 new 来进行内存分配呢? 上面已经讲到,因为他们都是Class类型,当然可以使用new 来进行内存分配.

  其次,CLR执行这样的代码的时,CLR 通过反射(有待考察)或者其他途径来获知所要请求分配内存的类型是否继承于System.ValueType如果是的话,那么就在栈上进行分配,如果不是的话,那么就是我们所说的引用类型,就在托管堆上分配内存以及栈上分配对应的引用变量,这些一切都是CLR做的工作.

  我们再来看看装箱操作.

  object o = new object();

  Int32 aaa = 100;

  o = aaa; //这里会发生装箱操作

  我们都知道当CLR执行到 o = aaa;这条语句时会发生装箱操作,为什么会发生装箱操作呢?这是因为CLR 知道引用变量o所要引用的类型aaa是继承于System.ValueType类型的,继承于System.ValueType的类型都是在栈上分配的,而其它则是在托管堆上分配的,所以会CLR会弄得aaa的副本弄到托管堆上去,这一切也都是CLR的工作.

  由此我们可以得出结论:

  1.在C#中 就代码层面上讲 所有的类型都是Class类型.

  2.所谓的 "值类型" != 数值类型,而是所有继承于System.ValueType 的类型.

  3."值类型" 得到的语言级别的支持,CLR知道如何对 "值类型" 这样的Class类型进行内存分配和处理.

收获园豆:50
悟行 | 专家六级 |园豆:12559 | 2012-04-27 21:59

我也有了这个疑惑,谢谢您解决了我的疑惑,不过您说继承于System.ValueType的类型都是在栈上分配的,有一个例外Enum。

方小白 | 园豆:202 (菜鸟二级) | 2016-07-22 21:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册