代码改变世界

《你必须知道的.NET》读后小结(1)

2012-03-12 22:28  Oliver_Zhao  阅读(196)  评论(0编辑  收藏  举报

  首先,这个文章是对《你必须知道的.Net》的读后小结,还有出于自己的方便才写的,以后还会对其他章节进行总结。有一定.net基础的人,可以瞄一下。.Net基础很好的或者看过《你必须知道的.Net》书的人,可以回顾一下。如果文章有什么错误,感谢大家指出。2012-03-12

《你必须知道的.NET》读后小结(1)

值类型和引用类型:

  值类型(Value Type),值类型通常分配在线程栈(stack)上,并不包含任何指向实例数据的指针,因为变量本身就包含了其实例数据。这里就有一个问题,如果一个值类型作为一个类的成员时,那么这个值类型在内存中是怎么样的?答案:它被存放在托管堆(managed heap)上。那么常见的值类型你能举例出几个呢?Color,DateTime这两个常用的数据类型,又到底是值类型,还是引用类型呢?

  引用类型(Reference Type),引用类型实例分配在托管堆(managed heap)上,变量保存了实例数据的内存引用。在上面,我们讨论了一个值类型作为一个类的成员变量时,这个值类型在内存上的分配情况,那么如果一个值类型如果包含了一个引用类型的成员变量呢(用Struct就可以实现哦^_^)?答案:值类型必定存放在线程栈上,而它的引用类型的成员的引用,将被存放在这个值类型的线程栈上。

String类型:

  我曾经面试过一些人,我问,在.Net中,string是什么类型?竟然真有些人回答string是值类型。- -!!。记住啊!!string是一个特殊的引用类型,具有不变性(Immutability),每次对string的改变都会在托管堆中产生一个新的string变量。另外,string类重载了==操作符,比较的是实际的字符串,而不是引用的地址。

特殊操作:

  • ref和out:这两个值类型按照引用方式传递。当然引用类型也同样能打这两个操作符。注意了,在ref传递参数之前必须初始化;而out则在传递前不必初始化,且传递时必须显示赋值。在Linq中不能对out参数赋值哦!
  • 引用类型和值类型之间的转换。Boxing/Unboxing。
  • sizeof()运算符用于值类型的大小,不适用于引用类型。
  • 值类型使用new来完成初始化,而单纯的定义没有完成初始化动作,此时对成员的引用将不能被编译通过。同时,当你定义了一个结构体,你想初始化一些默认值,写了一个无参的构造函数对成员变量赋值,你会发现编译器报错"Structs cannot contain explicit parameterless constructors"。可以在《CLR via C#》——Jeffrey Richter中找到原由。
  • 值类型都继承自System.ValueType,而System.ValueType又继承自System.Object,其主要区别在于值类型重写了Equals方法。

值类型与引用类型的比较

  • 值类型继承自System.ValueType(System.ValueType继承自System.Object);而引用类型继承自System.Object。
  • 值类型变量包含实例数据,每个变量保存了其本身的数据拷贝(副本),因此默认情况下,值类型的参数传递不影响参数本身;而引用类型变量存放了其数据的引用地址,因此以按值方式进行参数传递时会影响数本身,因为两个变量会引用内存中的同一地址。
  • 值类型的内存不受GC管理,当作用域结束时,值类型会自动释放。
  • 值类型是密封的(sealed),因此不能被继承,但是可以单继承或多继承接口。而引用类型一般如果不在声明的时候加上sealed,一般都是有继承性的。
  • 值类型不具有多态性;引用类型有多态性。
  • 值类型不能为null,在分配内存时自行初始化为0;而引用类型默认情况下,创建为null,表示没有指向任何托管堆的引用地址。
  • 值类型有两种状态:装箱和拆箱。

  首先,这个文章是对《你必须知道的.Net》的读后小结,还有出于自己的方便才写的。有一定.net基础的人,可以瞄一下。.Net基础很好的或者看过《你必须知道的.Net》书的人,可以回顾一下。如果文章有什么错误,感谢大家指出。

同时,自用,谢绝转载。22:26:01