装箱与拆箱的理解

合集下载

C#编程基础练习题与答案

C#编程基础练习题与答案

1.面向对象的思想主要包括什么?答:个人认为一各程序语言要成为真正的面向对象的程序设计语言,它必须符合下列条件: 1抽象(abstraction)—抽象能够有效地管理一个问题的复杂性,其作法是划分出与该问题相关的一组对象.2 封装(Encapsulation)—封装是指将一个抽象的内部实现隐藏在特定的对象之内.3 多态(polymorphism)—多态会提供相同方法的多种操作方法的多种操作实作.例如,不同的对象都会拥有一个Save方法,但是每一个Save方法会执行不同的操作.4 继承(inheritance)—Visual C# 2005 最令人兴奋之处就是其继承特性.v c#2005则提供了真正的方法继承,因此您可以重复使用一个类的实例.2.什么是中的用户控件自己动手作自己的控件来取代.NET提供的控件。

这种控件就是用户控件。

后缀为.ascx3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?什么是多态? CTS、CLS和CLR分别作何解释?应用程序域:应用程序域(通常是AppDomain)是用于隔离应用程序的虚拟进程。

在同一个应用程序作用域中创建的所有对象(换句话说,从该应用程序的入口点开始沿着对象激活序列的任何地方)都在同一个应用程序域中创建。

多个应用程序域可以存在于一个操作系统进程中,使它们成为隔离应用程序的简便方式。

操作系统进程通过使用各不相同的内存地址空间来提供隔离。

尽管它是有效的,但也是代价昂贵的,并且不能达到大型Web 服务器所需要的数量。

与其相比,公共语言运行时通过管理在应用程序域中运行的代码的内存使用来强制进行应用程序隔离。

这样就确保它不会访问应用程序域以外的内存。

需要注意的是,只有类型安全的代码才能以这种方式管理(当在应用程序域中加载不安全代码时,运行时不能保证隔离)。

理解应用程序域:应用程序域是.NET 运行库的逻辑进程表示,操作系统进程可以包含多个应用程序域。

装箱与拆箱及其性能损失问题

装箱与拆箱及其性能损失问题

装箱与拆箱及其性能损失问题⾸先我想了解⼀下什么是装箱和拆箱在类型系统中,任何值类型和引⽤类型都可以和object类型进⾏转化,装箱转化是指将⼀个值类型显式或者隐式的转化为⼀个object类型,或者是转化成⼀个被该值类型应⽤的接⼝类型,将⼀个值类型装箱,就创建了⼀个object实例,并且将这个值赋值给了object,object对象的数据位于堆中,在栈上有对该对象的引⽤,⽽被装箱的类型的值是被作为⼀个复制的⽂件赋给对象的,所谓拆箱,就是装箱操作的反操作,复制堆中的对象⾄栈中,并且返回其值。

性能损失:相⽐于简单的赋值操作,装箱和拆箱需要进⾏⼤量的计算,对值类型进⾏装箱时,需要分配并构造⼀个全新的对象。

为了解决装箱与拆箱带来的性能损失问题,微软公司在.NET中提供了泛型。

下⾯就让我们看⼀段代码:将5000000条记录写⼊到ArrayList并将数据读出来5遍,其中写⼊和读取ArrayList的⼯作就是装箱和拆箱,最后计算出执⾏这些⽅法所消耗的时间。

class Unbox{public static void RunUnbox(){int count;DateTime startTime = DateTime.Now;ArrayList MyArrayList = new ArrayList();for (int i = 0; i < 5; i++){MyArrayList.Clear();for (count = 0; count < 5000000; count++){MyArrayList.Add(count); //装箱}int j;for (count = 0; count < 5000000; count++){j = (int)MyArrayList[count];//拆箱}}DateTime endTime = DateTime.Now;Console.WriteLine("使⽤装箱和拆箱共花时间:{0}",endTime-startTime);}public static void RunNoBox(){int count;DateTime startTime = DateTime.Now;List<int> MyTList = new List<int>();for (int i = 0; i < 5; i++){MyTList.Clear();for (count = 0; count < 5000000; count++){MyTList.Add(count);}int j;for (count = 0; count < 5000000; count++){j = MyTList[count];}}DateTime endTime = DateTime.Now;Console.WriteLine("使⽤泛型共花时间:{0}", endTime - startTime);}}class Test{static void Main(string[] args){Unbox.RunUnbox();Unbox.RunNoBox();Console.ReadLine();}}下⾯是运⾏结果:使⽤装箱和拆箱共花时间:00:00:04.2500000使⽤泛型共花时间:00:00:00.4687500由运⾏结果可以发现,即使是进⾏同样的操作,使⽤装箱和拆箱所使⽤的时间是使⽤泛型所花时间的10倍。

C#面试题整理(带答案)

C#面试题整理(带答案)

C#⾯试题整理(带答案)1.维护数据库的完整性、⼀致性、你喜欢⽤触发器还是⾃写业务逻辑?为什么?答:尽可能⽤约束(包括CHECK、主键、唯⼀键、外键、⾮空字段)实现,这种⽅式的效率最好;其次⽤触发器,这种⽅式可以保证⽆论何种业务系统访问数据库都能维持数据库的完整性、⼀致性;最后再考虑⽤⾃写业务逻辑实现,但这种⽅式效率最低、编程最复杂,当为下下之策。

2.什么是事务?什么是锁?答:事务是指⼀个⼯作单元,它包含了⼀组数据操作命令,并且所有的命令作为⼀个整体⼀起向系统提交或撤消请求操作,即这组命令要么都执⾏,要么都不执⾏。

锁是在多⽤户环境中对数据的访问的限制。

SqlServer⾃动锁定特定记录、字段或⽂件,防⽌⽤户访问,以维护数据安全或防⽌并发数据操作问题,锁可以保证事务的完整性和并发性。

3.什么是索引,有什么优点?答:索引象书的⽬录类似,索引使数据库程序⽆需扫描整个表,就可以在其中找到所需要的数据,索引包含了⼀个表中包含值的列表,其中包含了各个值的⾏所存储的位置,索引可以是单个或⼀组列,索引提供的表中数据的逻辑位置,合理划分索引能够⼤⼤提⾼数据库性能。

4.视图是什么?游标是什么?答:视图是⼀种虚拟表,虚拟表具有和物理表相同的功能,可以对虚拟表进⾏增该查操作;视图通常是⼀个或多个表的⾏或列的⼦集;视图的结果更容易理解(修改视图对基表不影响),获取数据更容易(相⽐多表查询更⽅便),限制数据检索(⽐如需要隐藏某些⾏或列),维护更⽅便。

游标对查询出来的结果集作为⼀个单元来有效的处理,游标可以定位在结果集的特定⾏、从结果集的当前位置检索⼀⾏或多⾏、可以对结果集中当前位置进⾏修改、5.什么是存储过程?有什么优点?答:存储过程是⼀组予编译的SQL语句它的优点:1.允许模块化程序设计,就是说只需要创建⼀次过程,以后在程序中就可以调⽤该过程任意次。

2.允许更快执⾏,如果某操作需要执⾏⼤量SQL语句或重复执⾏,存储过程⽐SQL语句执⾏的要快。

C#装箱拆箱和性能

C#装箱拆箱和性能

C#装箱拆箱和性能C#装箱拆箱和性能 - My Soul For You[5:34]有收获就写下来。

⾸先,说⼀下装箱和拆箱。

在.net中的通⽤类型系统(Common Type system,CTS)中,所有类型都是对象(object),都派⽣⾃System.Object。

CTS⽀持两组类型:值类型和引⽤类型。

如果变量是值类型那么这个变量就包含实际的数据。

也就是在内存中确实会分配那么⼀部分空间给这个变量并存储值,引⽤类型就类似⼀个类型安全的指针,本⾝并没有开辟内存空间去存储东西。

这玩意是基础,罗嗦的重复⼀下。

⽽装箱(box)就是将值类型转换为引⽤类型的过程。

相反的过程就叫拆箱(unbox)。

a、装箱⼀个很简单的例⼦。

新建⼀个控制台程序,在Main()⾥⾯就写两句话。

int i = 13;object ob = i;编译。

然后⽤.net 提供的⼯具ILDASM.exe(MSIL Disassembler )查看新⽣产这个程序的配件代码(Microsoft intermediate language ,MSIL。

顺带说⼀句.net framework SDK除了这个MSIL的反汇编⼯具,当然还提供了汇编⼯具ILASM.exe,可以使⽤MSIL编写程序,当然。

谁也不会没事这么⼲。

那个反汇编⼯具倒是挺有⽤,可以了解⼀些底层机制)⽤那个⼯具查看⼀下编译后程序的Main(string[] args)⽅法,显⽰如下(我现在⽤的时.net framework 2.0可能MSIL代码显⽰出来的和原来的1.0或者1.1稍有不同,不过没关系核⼼没变):.method private hidebysig static void Main(string[] args) cil managed{.entrypoint// Code size 12 (0xc).maxstack 1.locals init ([0] int32 i,[1] object ob)IL_0000: nopIL_0001: ldc.i4.s 13IL_0003: stloc.0IL_0004: ldloc.0IL_0005: box [mscorlib]System.Int32IL_000a: stloc.1IL_000b: ret} // end of method Program::Main稍微解释⼀下:(1)先注意 .locals ,定义了两个类型分别为int32 和object 的局部变量(2)然后看 IL_0001处,ldc是个指令,后⾯的i4.s指出作为32位(4个字节)整数被压⼊堆栈。

装箱跟拆箱的概念

装箱跟拆箱的概念

装箱跟拆箱的概念
装箱和拆箱是两个在计算机科学中常用的术语,主要用于描述将数据从一种类型转换为另一种类型的操作。

装箱(boxing)是指将一个值类型(如整数、浮点数、字符等)封装为对应的引用类型(如整数类、浮点数类、字符类等)的过程。

在Java中,装箱通常是由编译器自动完成的,例如将int类型的整数自动装箱为Integer类型的对象。

装箱的过程会对原始数据进行封装,使其具有更多的功能,但也会引入一定的性能开销。

拆箱(unboxing)是指将一个引用类型(如包装类对象)解包为对应的值类型(如基本数据类型)的过程。

在Java中,拆箱通常也是由编译器自动完成的,例如将Integer类型的对象自动拆箱为int类型的整数。

拆箱的过程会将引用类型的数据还原为原始的值类型,以便进行计算或其他操作。

装箱和拆箱的概念在Java中特别重要,因为一些集合类(如List、Set)只能存储引用类型的数据,而不能直接存储值类型的数据。

因此,在需要将值类型数据存储到集合类中时,编译器会自动进行装箱操作,将值类型数据封装成引用类型对象存储到集合中;在需要从集合中取出数据进行计算时,编译器会自动进行拆箱操作,将引用类型对象还原为原始值类型进行计算。

这使得值类型的数据可以和引用类型的数据一样方便地在集合类中进行操作。

计算机专业应用面试题

计算机专业应用面试题

计算机专业应用面试题1. new 关键字用法(1)new 运算符用于创建对象和调用构造函数。

(2)new 修饰符用于向基类成员隐藏继承成员。

(3)new 约束用于在泛型声明中约束可能用作类型参数的参数的类型。

2.如何把一个Array复制到ArrayList里(1) 实现1string[] s ={ "111", "22222" };ArrayList list = new ArrayList();list.AddRange(s);(2)实现2string[] s ={ "111", "22222" };ArrayList list = new ArrayList(s);3.DataGrid的Datasouse可以连接什么数据源l DataTablel DataViewl DataSetl DataViewManagerl 任何实现IListSource接口的组件l 任何实现IList接口的组件4.概述反射和序列化反射公共语言运行库加载器管理应用程序域。

这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。

程序集包含模块,而模块包含类型,类型又包含成员。

反射则提供了封装程序集、模块和类型的对象。

您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。

然后,可以调用类型的方法或访问其字段和属性。

序列化序列化是将对象状态转换为可保持或传输的格式的过程。

与序列化相对的是反序列化,它将流转换为对象。

这两个过程结合起来,可以轻松地存储和传输数据。

5.概述O/R Mapping 的原理利用反射,配置将对象和数据库表映射。

6. 可访问性级别有哪几种l public 访问不受限制。

l protected 访问仅限于包含类或从包含类派生的类型。

l internal 访问仅限于当前程序集。

关于C#装箱与拆箱的理解

关于C#装箱与拆箱的理解

关于C#装箱与拆箱的理解NET重要技术和基础之一的CTS(Common Type System)。

顾名思义,CTS就是为了实现在应用程序声明和使用这些类型时必须遵循的规则而存在的通用类型系统。

.Net将整个系统的类型分成两大类——V alue Type 和Reference Type。

,多数的OO语言存在这个弱点,原因就是因为他们的原类型没有共同的基点,于是他们在本质上并不是真正的对象C++更依赖于对象,而非面向对象。

.Net环境的CTS 给我们带来了方便。

第一、CTS中的所有东西都是对象;第二、所有的对象都源自一个基类——System.Object类型。

这就是所谓的单根层次结构(singly rooted hierarchy)关于System.Object的详细资料请参考微软的技术文档。

CTS V alue Type的一个最大的特点是它们不能为null,V alue Type的变量总有一个值。

在传递V alue Type的变量时,实际传递的是变量的值,而非底层对象的“引用”。

CTS Reference Type就好像是类型安全的指针,它可以为null。

当值为null时,说明没有引用或类型指向某个对象。

声明一个引用类型的变量时,被操作的是此变量的引用(地址),而不是数据。

1、装箱和拆箱是一个抽象的概念2、装箱是将值类型转换为引用类型;拆箱是将引用类型转换为值类型利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来例如:int val = 100;object obj = val;Console.WriteLine (“对象的值= {0}", obj);这是一个装箱的过程,是将值类型转换为引用类型的过程int val = 100;object obj = val;int num = (int) obj;Console.WriteLine ("num: {0}", num);这是一个拆箱的过程,是将值类型转换为引用类型,再由引用类型转换为值类型的过程注:被装过箱的对象才能被拆箱3、.NET中,数据类型划分为值类型和引用(不等同于C++的指针)类型,与此对应,内存分配被分成了两种方式,一为栈,二为堆,注意:是托管堆。

装箱跟拆箱的概念

装箱跟拆箱的概念

装箱跟拆箱的概念装箱和拆箱是物流行业中非常重要的概念,它们涉及到货物的包装、运输和处理,对于保障货物的安全和有效进行运输具有重要意义。

在这篇文章中,我将深入解释装箱和拆箱的概念,以及它们在物流中的作用和意义。

首先,让我们来看一下装箱的概念。

装箱,顾名思义就是把货物放入箱子或其他包装容器中,以便进行运输或储存。

在装箱过程中,我们需要考虑到货物的性质、尺寸、重量以及运输方式等因素,选择合适的包装容器,并采取相应的包装方式,确保货物在运输途中不受损坏或丢失。

装箱工作需要有经验和技巧,以确保货物能够安全地到达目的地,减少货物损坏的风险。

装箱的重要性不言而喻。

首先,它可以保护货物免受损坏或丢失。

良好的包装可以有效地减少货物在运输途中受到的冲击和摩擦,避免货物因碰撞或挤压而损坏。

其次,装箱可以提高货物的运输效率。

合适的包装容器和包装方式可以使货物更加紧凑和整齐地摆放,减少货物在运输途中的体积和重量,从而减少运输成本。

此外,装箱还可以提升货物的形象和品质。

精美的包装不仅可以增加货物的吸引力,还可以给客户留下好的印象,提高客户的满意度和信任度。

接下来,让我们转到拆箱的概念。

拆箱就是把货物从包装容器中取出的过程。

在货物到达目的地后,我们需要进行拆箱操作,将货物从包装容器中取出,并进行相应的处理和存放。

拆箱工作同样也是需要技巧和经验的,以避免货物在拆箱过程中受到损坏。

拆箱的作用和意义也是不可或缺的。

首先,拆箱可以让货物得到妥善的处理和存放。

在货物到达目的地后,我们需要对货物进行检查、分类和存放,以保证货物的安全和完整。

其次,拆箱可以帮助我们对货物进行质量和数量的核对。

通过拆箱操作,我们可以及时发现货物的异常和问题,进行相应的处理和解决。

同时,拆箱也是供应链管理中的一个重要环节,对于货物的流通和分配有着重要的作用。

总的来说,装箱和拆箱是物流行业中不可或缺的两个环节,它们对于保障货物的安全和有效进行运输具有重要意义。

合理、科学地进行装箱和拆箱工作,可以有效地降低货物在运输途中的风险,提高货物运输的效率和质量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于C#装箱与拆箱的理解NET重要技术和基础之一的CTS(Common Type System)。

顾名思义,CTS就是为了实现在应用程序声明和使用这些类型时必须遵循的规则而存在的通用类型系统。

.Net将整个系统的类型分成两大类——Value Type 和 Reference Type。

,多数的OO语言存在这个弱点,原因就是因为他们的原类型没有共同的基点,于是他们在本质上并不是真正的对象C++更依赖于对象,而非面向对象。

.Net环境的CTS 给我们带来了方便。

第一、CTS中的所有东西都是对象;第二、所有的对象都源自一个基类——System.Object类型。

这就是所谓的单根层次结构(singly rooted hierarchy)关于System.Object的详细资料请参考微软的技术文档。

CTS Value Type的一个最大的特点是它们不能为null,Value Type的变量总有一个值。

在传递Value Type的变量时,实际传递的是变量的值,而非底层对象的“引用”。

CTS Reference Type就好像是类型安全的指针,它可以为null。

当值为null时,说明没有引用或类型指向某个对象。

声明一个引用类型的变量时,被操作的是此变量的引用(地址),而不是数据。

1、装箱和拆箱是一个抽象的概念2、装箱是将值类型转换为引用类型;拆箱是将引用类型转换为值类型利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来例如:int val = 100;object obj = val;Console.WriteLine (“对象的值 = {0}", obj);这是一个装箱的过程,是将值类型转换为引用类型的过程int val = 100;object obj = val;int num = (int) obj;Console.WriteLine ("num: {0}", num);这是一个拆箱的过程,是将值类型转换为引用类型,再由引用类型转换为值类型的过程注:被装过箱的对象才能被拆箱3、.NET中,数据类型划分为值类型和引用(不等同于C++的指针)类型,与此对应,内存分配被分成了两种方式,一为栈,二为堆,注意:是托管堆。

值类型只会在栈中分配。

引用类型分配内存与托管堆。

托管堆对应于垃圾回收。

4:装箱/拆箱是什么?装箱:用于在垃圾回收堆中存储值类型。

装箱是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。

拆箱:从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。

5:为何需要装箱?(为何要将值类型转为引用类型?)一种最普通的场景是,调用一个含类型为Object的参数的方法,该Object可支持任意为型,以便通用。

当你需要将一个值类型(如Int32)传入时,需要装箱。

另一种用法是,一个非泛型的容器,同样是为了保证通用,而将元素类型定义为Object。

于是,要将值类型数据加入容器时,需要装箱。

6:装箱/拆箱的内部操作。

装箱:对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。

按三步进行。

第一步:新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。

第二步:将值类型的实例字段拷贝到新分配的内存中。

第三步:返回托管堆中新分配对象的地址。

这个地址就是一个指向对象的引用了。

有人这样理解:如果将Int32装箱,返回的地址,指向的就是一个Int32。

我认为也不是不能这样理解,但这确实又有问题,一来它不全面,二来指向Int32并没说出它的实质(在托管堆中)。

拆箱:检查对象实例,确保它是给定值类型的一个装箱值。

将该值从实例复制到值类型变量中。

有书上讲,拆箱只是获取引用对象中指向值类型部分的指针,而内容拷贝则是赋值语句之触发。

我觉得这并不要紧。

最关键的是检查对象实例的本质,拆箱和装箱的类型必需匹配,这一点上,在IL层上,看不出原理何在,我的猜测,或许是调用了类似GetType之类的方法来取出类型进行匹配(因为需要严格匹配)。

7:装箱/拆箱对执行效率的影响显然,从原理上可以看出,装箱时,生成的是全新的引用对象,这会有时间损耗,也就是造成效率降低。

那该如何做呢?首先,应该尽量避免装箱。

比如上例2的两种情况,都可以避免,在第一种情况下,可以通过重载函数来避免。

第二种情况,则可以通过泛型来避免。

当然,凡事并不能绝对,假设你想改造的代码为第三方程序集,你无法更改,那你只能是装箱了。

对于装箱/拆箱代码的优化,由于C#中对装箱和拆箱都是隐式的,所以,根本的方法是对代码进行分析,而分析最直接的方式是了解原理结何查看反编译的IL代码。

比如:在循环体中可能存在多余的装箱,你可以简单采用提前装箱方式进行优化。

8:对装箱/拆箱更进一步的了解装箱/拆箱并不如上面所讲那么简单明了,比如:装箱时,变为引用对象,会多出一个方法表指针,这会有何用处呢?我们可以通过示例来进一步探讨。

举个例子。

Struct A : ICloneable{public Int32 x;public override String ToString() {return String.Format(”{0}”,x);}public object Clone() {return MemberwiseClone();}}static void main(){A a;a.x = 100;Console.WriteLine(a.ToString());Console.WriteLine(a.GetType());A a2 = (A)a.Clone();ICloneable c = a2;Ojbect o = c.Clone();}5.0:a.ToString()。

编译器发现A重写了ToString方法,会直接调用ToString的指令。

因为A是值类型,编译器不会出现多态行为。

因此,直接调用,不装箱。

(注:ToString是A 的基类System.ValueType的方法)5.1:a.GetType(),GetType是继承于System.ValueType的方法,要调用它,需要一个方法表指针,于是a将被装箱,从而生成方法表指针,调用基类的System.ValueType。

(补一句,所有的值类型都是继承于System.ValueType的)。

5.2:a.Clone(),因为A实现了Clone方法,所以无需装箱。

5.3:ICloneable转型:当a2为转为接口类型时,必须装箱,因为接口是一种引用类型。

5.4:c.Clone()。

无需装箱,在托管堆中对上一步已装箱的对象进行调用。

附:其实上面的基于一个根本的原理,因为未装箱的值类型没有方法表指针,所以,不能通过值类型来调用其上继承的虚方法。

另外,接口类型是一个引用类型。

对此,我的理解,该方法表指针类似C++的虚函数表指针,它是用来实现引用对象的多态机制的重要依据。

9:如何更改已装箱的对象对于已装箱的对象,因为无法直接调用其指定方法,所以必须先拆箱,再调用方法,但再次拆箱,会生成新的栈实例,而无法修改装箱对象。

有点晕吧,感觉在说绕口令。

还是举个例子来说:(在上例中追加change方法)public void Change(Int32 x) {this.x = x;}调用:A a = new A();a.x = 100;Object o = a; //装箱成o,下面,想改变o的值。

((A)o).Change(200); //改掉了吗?没改掉。

没改掉的原因是o在拆箱时,生成的是临时的栈实例A,所以,改动是基于临时A的,并未改到装箱对象。

(附:在托管C++中,允许直接取加拆箱时第一步得到的实例引用,而直接更改,但C#不行。

) 那该如何是好?嗯,通过接口方式,可以达到相同的效果。

实现如下:interface IChange {void Change(Int32 x);}struct A : IChange {…}调用:((IChange)o).Change(200);//改掉了吗?改掉了。

为啥现在可以改?在将o转型为IChange时,这里不会进行再次装箱,当然更不会拆箱,因为o已经是引用类型,再因为它是IChange类型,所以可以直接调用Change,于是,更改的也就是已装箱对象中的字段了,达到期望的效果。

10、将值类型转换为引用类型,需要进行装箱操作(boxing):1、首先从托管堆中为新生成的引用对象分配内存。

2、然后将值类型的数据拷贝到刚刚分配的内存中。

3、返回托管堆中新分配对象的地址。

可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。

将引用内型转换为值内型,需要进行拆箱操作(unboxing):1、首先获取托管堆中属于值类型那部分字段的地址,这一步是严格意义上的拆箱。

2、将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。

经过这2步,可以认为是同boxing是互反操作。

严格意义上的拆箱,并不影响性能,但伴随这之后的拷贝数据的操作就会同boxing操作中一样影响性能。

11、-------------------------NET的所有类型都是由基类System.Object继承过来的,包括最常用的基础类型:int, byte, short,bool等等,就是说所有的事物都是对象。

如果申明这些类型得时候都在堆(HEAP)中分配内存,会造成极低的效率!(个中原因以及关于堆和栈得区别会在另一篇里单独得说说!) .NET如何解决这个问题得了?正是通过将类型分成值型(value)和引用型(regerencetype),C#中定义的值类型包括原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct),引用类型包括:类、数组、接口、委托、字符串等。

值型就是在栈中分配内存,在申明的同时就初始化,以确保数据不为NULL;引用型是在堆中分配内存,初始化为null,引用型是需要GARBAGE COLLECTION来回收内存的,值型不用,超出了作用范围,系统就会自动释放!下面就来说装箱和拆箱的定义!装箱就是隐式的将一个值型转换为引用型对象。

比如:int i=0;Syste.Object obj=i;这个过程就是装箱!就是将i装箱!拆箱就是将一个引用型对象转换成任意值型!比如:int i=0;System.Object obj=i;int j=(int)obj;这个过程前2句是将i装箱,后一句是将obj拆箱!。

相关文档
最新文档