C# 经典实例 第一章 简介

类比结构灵活得多。结构可以跟类一样实现接口,但与类不同的是,他们不能继承自类或结构。这种限制使得你无法创建结构层次关系,而这用类可以做到。

通过抽象基类实现的多态性也是在结构中无法使用的,因为除了装箱成Object、ValueType和Enum,结构无法从另一个类派生。

结构与其他值类型一样,都是从System.ValueType隐式派生的。结构类似于类,但实际上有很大的差别。在设计应用程序时,知道何时使用结构优于使用类将有很大的帮助。不正确的使用结构可能使代码性能低下、难以修改。

结构相对于引用类型有两个性能优势:

  1. 如果一个结构是在栈上分配的(即不包含在引用类型内),访问结构及其数据的速度要快于访问堆中引用类型的速度。引用类型的对象必须要跟随他在对象的引用以获取数据。
  2. 要清理在栈上为结构分配的内存,只需要在方法调用返回时修改栈指针所指的地址即可。这个调用要远远快于垃圾回收器自动清理托管堆上分配的引用类型。然而垃圾回收器的成本是延后的,所以不会立刻被人注意到。

当以传值方式传入其他方法时,结构的性能就比不上类了。因为结构存在于栈上,当以传值方式传入一个方法时,结构及其数据必须复制到一个新的局部变量(方法用于接收结构的参数)中。这ige复制过程相比将一个引用传入方法要花费更多的时间,除非结构的大小与机器的指针大小相同或更小一些。因此,在32位的机器上,传入一个32位的小的结构与传入一个引用(与指针大小相同)的成本是相同的。在类和结构之间选择时,要记得这一点。尽管创建、访问和销毁类对象可能需要更长的时间,但并不能抵消将结构多次按值传入一个或多个方法产生的性能下降。保持较小的结构体可以减小按值传递时所产生的性能下降。

 以下情况使用类:

  • 其同一性很重要。结构在按值传入方法时会被隐式复制。
  • 有较大的内存占用。
  • 其字段需要初始化。
  • 需要从一个基类继承。
  • 需要多态行为。

以下情况使用结构:

  • 其行为方式类似于原语类型(int、long、byte等)
  • 仅占用较小的内存
  • 调用一个需要将结构体以传值方式传入P/Invoke方法。平台调用(Platform Invoke,P/Invoke)允许托管代码调用DLL内公开的非托管方法。许多时候,非托管DLL内的方法都需要传入一个结构参数。使用结构是执行此操作的一种高效方法,并且在需要按值传入时是唯一的途径。
  • 需要降低垃圾回收对应用程序性能的影响。
  • 其字段只需要被初始化为默认值。对于数值类型,这个值为0;bool类型则为false;对于引用类型,则为null。(注意在C#6.0中,结构可以拥有默认构造函数并将字段初始化位非默认值)
  • 不需要继承一个基类
  • 不需要多态行为

当把结构传递给需要一个对象参数的方法时,例如Framework类库(FCL)中的任何非泛型集合类型,他们也可能会引起性能降低。把一个结构(对此问题而言其实是任何简单类型)传入一个需要对象参数的方法中将会导致结构被装箱。装箱(boxing)是指将一个值类型包装在一个对象中。这种操作比较耗时,并且可能导致性能降低。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值