应用类型和值类型(转)

引用类型和值类型

CLR 支持两种类型:引用类型和值类型。

引用类型( reference type):从托管堆上分配。

  ① 内存必须从托管堆中分配

  ② 每个在托管堆中分配的对象都有一些与之关联的额外附加成员必须被初始化。

  ③ 从托管堆中分配的对象可能会导致执行垃圾收集。

如果我们代码中的每个类型都是引用类型的话,应用程序的性能将会大打折扣。设想如果每使用一个 Int32 值,系统都会出现一次内存分配,应用程序的性能该会有多糟糕。因此,CLR 提供了一直称作值类型的“轻量级”类型

值类型:通常分配在线程的堆栈上(也可以被嵌入到一个引用类型的对象中)

值类型实例的变量不包含指向实例的指针——变量本身即包含了实例所有的字段。因为变量本身包含了实例的所有字段,所以操作实例时也就无需再解析指针引用。

值类型实例不受垃圾收集器的控制。因此也减少了托管堆的压力,以及应用在整个生存期中需要垃圾回收的次数。

在设计自己的类型时,是将他们定义为值类型?还是引用类型?在满足一下所有表述时我们就可以考虑将类型声明为值类型。

  ① 该类型的行为类似于基元类型。

  ② 该类型不需要继承自任何其他类型。

  ③ 该类型不会被其他类型继承。

  ④ 该类型的实例不会频繁地用于方法的参数传递。默认情况下,参数以传值的方式传递,这会导致值类型实例中的字段被拷贝,从而损伤应用程序性能。

  ⑤ 该类型的实例不会作为方法的结果频繁地返回。从方法中返回一个值类型也会导致实例中的字段被拷贝到调用者分配的内存中,因此也会损伤应用程序的性能。

  ⑥ 该类型的实例不会被频繁地用于诸如 ArrayList 、 Hashtable之类的集合中。这些管理一组通用对象集合的类会对值类型实例执行装箱操作,这将导致额外的内存分配,以及额外的内存拷贝操作,从而也会损伤应用程序的性能。

值类型和引用类型的差别:

  ① 值类型对象有两种表示:一种是未装箱( unboxed )形式,一种是装箱( boxed )形式。引用类型总是装箱形式。

  ② 值类型都继承自 System.ValueType。 System.ValueType 没有在 System.Object 之外定义任何新的方法。但是,System.ValueType 重写了其中的 Equals 方法。当两个 ValueType 对象的字段相互匹配时, Equlas 方法会返回 true。另外,System.ValueType 还重写了 GetHashCode 方法,它会使用对象的实例字段并根据一定的算法来产生一份散列码值。当定义自己的值类型是,我们应该重写 Equals 和 GetHashCode方法。

  ③ 因为我们声明的值类型或引用类型不能以一个值类型作为基类,所以我们不应该向值类型中引入任何新的虚方法。值类型中更不可以有任何的抽象方法,所有的方法都隐含为密封( sealed )方法(即不能重写 );

  ④ 引用类型变量包含着对象在托管中的内存地址。默认情况下,当一个引用类型变量被创建时,它被初始值为 null ,表示该引用类型变量目前没有指向一个有效的对象。试图使用 null 引用类型变量会抛出一个 NullReferenceException 异常。相反,值类型变量总是包含一个符合它类型的值,并且所有的字段都被初始化为 0 值。当访问一个值类型是,不可能产生NullReferenceException 异常。

  ⑤ 当将一个值类型变量赋值给另一个值类型变量时,会进行一个 “字段对字段”的拷贝。但当将一个引用类型变量赋值给另一个引用类型变量时,只会拷贝内存地址。

  ⑥ 因为前一点,两个或多个引用类型变量可以指向托管堆中的同一个对象,这样对一个变量的操作将会影响到其它变量引用的对象。另一方面,每个值类型变量都有一份自己的“对象”数据拷贝,对一个值类型变量的操作不可能影响到另一个。

  ⑦ 因为未装箱值类型没有分配在托管堆上,所以一旦定义该类型实例的方法不再处于活动状态,为它们分配的存储空间就会立即释放。这意味着值类型实例在内存被回收时不可能收到任何通知(Finalize 方法)。

时间: 2024-11-05 22:33:53

应用类型和值类型(转)的相关文章

匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置

匹夫细说C#:不是"栈类型"的值类型,从生命周期聊存储位置 c#语言规范 阅读目录 0x00 前言: 0x01 堆vs栈? 0x02 谁"能"使用栈? 0x03 结论 0x04 后记补充 回到目录 0x00 前言: 匹夫在日常和别人交流的时候,常常会发现一旦讨论涉及到"类型",话题的热度就会立马升温,因为很多似是而非.或者片面的概念常常被人们当做是全面和正确的答案.加之最近在园子看到有人翻译的<C#堆vs栈>系列,觉得也挺有趣,挺不错

C# 类型基础 值类型和引用类型

引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复制(Shallow Copy)和深度复制(Deep Copy),浅度复制和深度复制又是以如何复制引用类型成员来划分的.由此又引出了引用类型和值类型,以及相关的对象判等.装箱.拆箱等基础知识.索性从最基础的类型开始自底向上写起. 值类型和引用类型 先简单回顾一下C#中的类型系统.C# 中的类型一共分为

可空值类型与值类型这间的转换

int s = 5; int? s_null; long t; long? t_null; t = s; //隐式转换 S -> T s = (int)t; //显示转换 T -> S s_null = s; //隐式转换 S -> S? s = (int)s_null; //显示转换 S? -> T t_null = s_null; //隐式转换 S? -> T? s_null = (int?)t_null; //显示转换 T? -> S? t_null = s; /

C#中的基元类型、值类型和引用类型

C# 中的基元类型.值类型和引用类型 1. 基元类型(Primitive Type) 编译器直接支持的类型称为基元类型.基元类型可以直接映射到 FCL 中存在的类型.例如,int a = 10 中的 int 就是基元类型,其对应着 FCL 中的 System.Int32,上面的代码你完全可以写作System.Int32 a = 10,编译器将生成完全形同的 IL,也可以理解为 C# 编译器为源代码文件中添加了 using int = System.Int32. 1.1 基元类型的算术运算的溢出检

C#-变量类型(值类型、引用类型)

第一次发这样的笔记呢! 这个是在再读基础的时候感觉自己理解的东西吧 变量的类型差异在数据的存储方式不一样,值类型是变量本身直接存储数据,另一个则是存储实际变量的引用, 值类型:都是存储在栈中的,都是直接访问实例,不能为null (如果存储的数据大于类型规定就会出现溢出和异常) 引用类型:需要New实例化,在堆中开辟的空间然后是在栈中引用的地址,

函数式编程:容器类型、值类型

容器类型:高阶类型: 例子:集合类容器.枚举类容器.结果类容器.适配类容器. 功能: 1.值类型的封装和解封: 2.值类型的管理:存储.遍历.查询:为高阶函数: 3.惰性求值的管理:处理函数的保存.处理函数的执行(apply). 值类型: 代表数据:用于进行处理,对应transform. 值类型的产生: 1.输入: 2.内部计算. 原文地址:https://www.cnblogs.com/feng9exe/p/9785638.html

【转】c#引用类型与值类型的区别大盘点

解析:CLR支持两种类型:值类型和引用类型.用Jeffrey Richter(<CLR via C#>作者)的话来说,“不理解引用类型和值类型区别的程序员将会把代码引入诡异的陷阱和诸多性能问题”.这就要求我们正确理解和使用值类型和引用类型. 值类型包括C#的基本类型(用关键字int.char.float等来声明),结构(用struct关键字声明的类型),枚举(用enum关键字声明的类型):而引用类型包括类(用class关键字声明的类型)和委托(用delegate关键字声明的特殊类).C#中的每

C#引用类型和值类型的区别

1***.C#中有两种类型: 值类型和引用类型: 值类型的变量直接包含他们的数据,而引用类型的变量存储 引用类型存储对他们的数据的引用,后者称为对象: 简单说:值类型直接存储其值,引用类型存储对值得引用.引用类型分为引用和引用的对象. 2***. 值类型:简单类型.枚举.结构 引用类型: 类类型.接口类型.数组类型和委托类型 3***.值类型与引用类型的内存存储 单纯的说值类型存储在栈上,引用类型存储在托管堆上是不对的. 4***.区别: 1. 托管堆: 同步块和方法表, x,y,托管堆上的需要

C#中值类型和引用类型

本文将介绍C#类型系统中的值类型和引用类型,以及两者之间的一些区别.同时,还会介绍一下装箱和拆箱操作. 值类型和引用类型 首先,我们看看在C#中哪些类型是值类型,哪些类型是引用类型. 值类型: 基础数据类型(string类型除外):包括整型.浮点型.十进制型.布尔型. 整型(sbyte.byte.char.short.ushort.int.uint.long.ulong ) 浮点型(float 和 double ) 十进制型(decimal ) 布尔型(bool ) 结构类型(struct) 枚