http://www.cnblogs.com/coolbeibei/archive/2009/03/23/1419706.html

实际举例C#引用类型和值类型的区别

我们都知道,c#的两大数据类型分别为值类型和引用类型。很多人或许闭着眼睛都能说出值类型包括简单类型、结构体类型和枚举类型,引用类型包括自定义类、数组、接口、委托等,但是当被问及到二者之间的联系和区别,什么时候用struct什么时候用class时,就常常混淆不清了。为此,了解值类型和引用类型的本质差异就变的很有必要了。

  1. 值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。因此,一个值类型变量就永远不会影响到其他的值类型变量,而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。
  2. 从内存分配上来看,值类型通常分配在线程的堆栈上,作用域结束时,所占空间自行释放,效率高,无需进行地址转换,而引用类型通常分配在托管堆上,由GC来控制其回收,需要进行地址转换,效率降低,这也正是c#需要定义两种数据类型的原因之一。
  3. 值类型均隐式派生自System.ValueType,而System.ValueType又直接派生于System.Object,每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,注意所有的值类型都是密封(sealed)的,所以无法派生出新的值类型。而且System.ValueType本身是一个类类型,而不是值类型,因为它重写了object的Equals()方法,所以对值类型将按照实例的值来比较,而不是比较引用地址。
  4. C# 的统一类型系统,使得值类型可以转化为对象来处理,这就是常说的装箱和拆箱。由于装拆箱需要装建全新对象或做强制类型转换,这些操作所需时间和运算要远远大于赋值操作,因此不提倡使用它,同时也要尽量避免隐式装拆箱的发生。

注:栈是操作系统分配的一个连续的内存区域,用于快速访问数据。因为值类型的容量是已知的,因此它可存储在栈上。而托管堆是CLR在应用程序启动时为应用程序预留的一块连续内存区,是用于动态内存分配的内存区,引用类型的容量只有到运行时才能确定,所有用堆来存储引用类型。

C#的两种数据类型延伸之一--嵌套类型的内存分配

对于引用类型嵌套值类型,以及值类型嵌套引用类型的情况下,内存分配可以根据以下两条规律来判断:

•     引用类型始终部署在托管堆上;

•     值类型总是分配在它声明的地方:作为字段时,跟随其所属的对象存储;作为局部变量时,存储在栈上。

C#的两种数据类型延伸之二--string类型

string是一个很有意思的引用类型,为什么说它很有意思呢?因为它表现了很多值类型的特点。请看一下代码示例:

示例1

string str1 = "abc";

string str2 = str1;

str1 = "123";

Console.WriteLine(str2);

示例2(msdn上的例子)

string a = "hello";

string b = "h";

// Append to contents of 'b'

b += "ello";

Console.WriteLine(a == b);

示例1的输出结果是abc,改变str1的值对str2没有影响。

示例2的输出结果是True。

这样的结果会使我们误以为string就是值类型。其实不然,示例1中str1 = "123"语句编译器私底下创建了一个新的字符串对象来保存新的字符序列"123",也就是此str1已非彼str1了,“此”str1的值的改变也就不能影响“彼”str1的值了,当然str2的值也就不会改变了。实质上str1 = "123"是str1=new string("123")的简写,它的每一次赋值都会抛掉原来的对象而生成一个新的字符串对象,分配新的内存空间,因此string是不可改变的。如果要创建可修改的字符串,可使用stringbuilder以获得更好的性能。至于示例2是因为为了方便比较字符串的值重定义了string的运算符==!=

C#的两种数据类型延伸之三--struct和class

class和struct的语法基本相同,从声明到使用,都很相似。但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到,也就是说struct都能被class所代替。那么为什么还要使用struct呢?存在即是合理的,struct在很多方面有着性能优势。让我们看看它们的主要区别在哪里?

  • 数据类型不一样,struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异。由于堆栈的执行效率要比堆的执行效率高,但是堆栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑。
  • 从继承性来看,struct既不能继承也不能被继承,但是可以实现接口,而Class就可以完全扩展了。
  • 内部结构有区别,struct只能添加带参的构造函数,不能使用abstract和protected等修饰符,不能初始化实例字段,但是值得注意的是,struct可以重写System.Object的3个虚方法,Equals()、ToString()和GetHashTable(),Class没有这些限制。

比较struct和class的不同,可以得出以下几条struct和class的使用原则:

1 在表示诸如点、矩形等主要用来存储数据的轻量级对象时,首选struct。

2 在表示数据量大、逻辑复杂的大对象时,首选class。

3 在表现抽象和多级别的对象层次时,class是最佳选择

转载于:https://www.cnblogs.com/Jessy/archive/2011/07/22/2114086.html

[转载]实际举例C#引用类型和值类型的区别相关推荐

  1. 跟小静读CLR via C#(02)-基元类型、引用类型、值类型

    跟小静读CLR via C#(02)-基元类型.引用类型.值类型 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架类库FCL存在着直接的映 ...

  2. .NET引用类型与值类型

    值类型和引用类型的基类 引用类型和值类型都继承自System.Object类.不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即直接继承System.Valu ...

  3. .net 基元类型,引用类型和值类型

    基元类型(primitive type): 编译器直接支持的数据类型称为基元类型(primitive type). string 与 String: 由于C#中的string (一个关键字)直接映射到 ...

  4. 第五章 基元类型、引用类型、值类型 CLR学习第五课

    一.基元类型:编译器直接支持的数据类型称为基元类型(如int类型其对于的是system.int32). 二.类型溢出,可以用checked 和unchecked进行类型溢出检查和不进行类型溢出检查.一 ...

  5. 第五章 基元类型,引用类型和值类型

    目录 5.1 编程语言的基元类型 5.2 引用类型和值类型 5.3 值类型的装箱和拆箱 5.4 对象哈希码 5.5 dynamic基元类型 5.1 编程语言的基元类型 编译器直接支持的数据类型称为基元 ...

  6. 《CLR via C#》读书笔记 之 基元类型、引用类型和值类型

    第五章 基元类型.引用类型和值类型 2013-02-27 5.3 值类型的装箱和拆箱     5.3.2 对象的相等性和同一性 参考 ToDo: 什么时候使用值类型,什么时候使用引用类型 5.3 值类 ...

  7. 《.NET框架程序设计》第5章 基元类型、引用类型与值类型

    5.1 基元类型 基元类型可以用快捷语法.比如int a=0;等同于System.Int32 a=new System.Int32(); 建议,使用全名,为了代码含义看起来更清晰. 5.1.1 Che ...

  8. 读书笔记_CLR.via.c#第五章_基元类型_引用类型_值类型

    基元类型 1.不管在什么操作系统上c#的int始终代表32位整数. 2.c#中long代表64位. 类型转换 安全转换时,才允许隐式转型. 不安全转换时,为显式转型. 溢出检测方法 控制溢出的一个办法 ...

  9. 浅析.NET中的引用类型和值类型(上)

    .NET中的类型分为值类型和引用类型,他们在内存布局,分配,相等性,赋值,存储以及一些其他的特性上有很多不同,这些不同将会直接影响到我们应用程序的效率.本文视图对.NET 基础类型中的值类型和引用类型 ...

最新文章

  1. python opencv 录制视频_OpenCV Python 录制视频
  2. 5G精华问答 | 5G是否会“逼退”4G?
  3. android 如何 root权限获取,如何获取android手机root权限获取
  4. Android Debug Bridge 技术实现原理
  5. HTML下拉菜单代码实现
  6. devExpress各个版本的下载地址收藏
  7. Vista Ultimate X64 绝对正宗的激活工具
  8. android课程设计的需求分析,安卓课程设计心得体会.doc
  9. 短视频封面抽取和标题自动化生成
  10. netty框架中 bossGroup与workGroup是一个还是两个Reactor
  11. STM32 USB HID的GET_REPORT 与 SET_REPORT请求
  12. 单片机上电后没有运转,需要从这些方面考虑
  13. 【观察】OceanBase 4.0,单机与分布式的新拐点
  14. 张艺谋的2008随笔
  15. macOS Monterey 12.5 (21G72) 正式版 ISO、IPSW、PKG 下载
  16. 信号量机制实现进程互斥与同步,生产者消费者
  17. (最新最详细)ADT安装和Eclipse的window-->preferences(首选项)没Android
  18. Oracle 表创建和表管理
  19. GOF设计模式之单例模式
  20. SolidWorks

热门文章

  1. C++中的istringstream 的用法
  2. 栈的逆转(递归实现)
  3. 讲解泊松融合文章推荐
  4. 第四讲 一阶线性ODE换元法
  5. vsCode格式化插件
  6. XML和实体类之间相互转换(序列化和反序列化)
  7. Java是如何加载资源文件的?(源码解毒)
  8. Polymorphic form--多态表单
  9. 织梦DedeCMS播放本地视频文件插件
  10. UA MATH567 高维统计专题3 含L1-norm的凸优化4 Nesterov方法与Accelerate Proximal Gradient