C#CLOdyssey via C#读书日记一’ 引用类型和值类型’

 

CL奥迪Q7扶助两类别型:引用类型和值类型。

  引用类型总是在托管堆上分配的,C#的new操作符会重返对象的内部存款和储蓄器地址——也正是指向目的数据的内部存款和储蓄器地址。

  使用引用类型必须小心到部分题材:

  1)内部存款和储蓄器必须从托管堆上分配。

  二)对上抽成的每种对象都有局地格外的成员(比如前边提到过得”项目对象指针“和”同步块索引“),那么些分子必须起先化。

  叁)对象中的别的字节(为字段而设)总是设为零。

  肆)从托管堆上分配二个对象时,可能强制执行二回垃圾回收操作。

  假如具有品类都是引用类型,应用程序的个性会明显下跌。为了升高简单的、常用的花色的属性,CL劲客提供了名字为”值类型”的轻量型类型。

  值类型的实例1般在线程栈上抽成的(纵然也可作为字段嵌入3个引用类型的目的中)。在象征值类型的实例的一个变量中,并不含有2个针对实例的指针。相反,变量中包涵了实例本身的字段。

  由于变量已经包蕴了实例的字段,所以为了操作实例中的字段,不再须求提供1个指南针。值类型的实例不受垃圾回收器的操纵。因而,值类型的利用缓解了托管堆中的压力,并减弱了2个应用程序在其生存期内须求开始展览的垃圾回收次数。

  .NET Framework
SDK文书档案分明建议,在翻看2个类型时,任何称为”类”的类型都以引用类型。如System.Exception类、System.Random类等援引类型。文档将有所值类型都改成结构或枚举。如System.Int3二协会、System.Boolean结构等值类型。

  全数值类型都必须从System.ValueType派生。全体枚举类型都从System.Enum抽象类派生,而System.Enum又是从System.ValueType派生的。CL奥迪Q5和具备编制程序语言都予以枚举特殊待遇,现在会提到。

  全体值类型都以隐式密封的(sealed),目标是严防将3个值类型用于其余任何引用类型或值类型的基类型。

  在托管代码中,要由定义类型的开发职员决定在如啥地方方分配项指标实例,使用该类型的人对此并无控制权。

  以下演示引用类型和值类型的区别:

//引用类型
class SomeRef 
{ 
    public Int32 x; 
} 
//值类型
struct SomeVal 
{ 
    public Int32 x; 
} 

static void Main(string[] args) 
{ 
    SomeRef r1 = new SomeRef();     //在堆上分配
    SomeVal v1 = new SomeVal();     //在栈上分配
    r1.x = 5; 
    v1.x = 5; 
    Console.WriteLine(r1.x);                //5 
    Console.WriteLine(v1.x);                //5 

    SomeRef r2 = r1; 
    SomeVal v2 = v1; 
    r1.x = 8; 
    v1.x = 9; 
    Console.WriteLine(r1.x);                //8 
    Console.WriteLine(r2.x);                //8 
    Console.WriteLine(v1.x);                //9 
    Console.WriteLine(v2.x);                //5 
} 

 

  唯有以下标准都能满意,不然不应有将三个项目表明成值类型:

  壹)类型具有基元类型的行为。

  二)类型不必要从任何任何类型继承

  3)类型也不会派生出此外类型。    

  类型实例的高低应该在思考之列,因为私下认可情状下,实参是以传值格局传递的,那会促成对值类型实例中的字段实行复制,从而影响性质量。同样的,被定义为回去三个值类型的四个方式在回来时,实例中的字段会赋值到调用者分配的内部存款和储蓄器中,从而影响属性。

  所以,采取值类型还应满足:

  1)类型的实例较小(约16字节要么更加小)

  二)类型的实例较大(大于1陆字节),但不作为方法的实参传递,也不从章程重返。

  值类型的首要性优势在于它们不作为对象在托管堆上分配。

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

  1)值类型对象有二种表示形式:未装箱(unboxed)和已装箱(boxed)。引用类型总是处于已装箱情势。

  二)值类型是从System.ValueType派生的。该品种提供了与System.Object定义的同1的秘籍。可是,System.ValueType重写了Equals方法和GetHashCode方法。由于那些暗许达成存在品质难点,所以定义自个儿的值类型时,应该重写Equals和GetHashCode方法,并提供它们的体现实现。

  三)值类型的拥有办法都不能够是虚幻的,而且全数办法都以隐式密封(sealed)方法。

  4)引用类型的变量包罗的是堆上的四个对象的地址。暗中认可意况,在创立三个引用类型的变量时,它被初步化为null,证明引用类型的变量当前不指向3个灵光对象。相反,值类型开始化是,全体的成员都会开首化为0。由于值类型的变量不是指针,所以在造访3个值类型时,不会抛出NullReferenceException非常。CL福特Explorer确实提供了三个例外的风味,能为值类型
添加”可空”标识。如”int?”

  5)
 将四个值类型的变量赋给另四个值类型变量,会执行三回逐字段复制。将引用类型赋给另1个引用类型时,只复制内部存款和储蓄器地址。

  6)由于为装箱的值类型不再堆上分配,所以只要定义了该类型的二个实例的章程不再处于活动状态,为她们分配的内存就会被保释。那意味着值类型的实例在其内部存款和储蓄器被回收时,不会因而Finalize方法接收到多少个公告。

 

相关文章