国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

[CLR via C#]5.2 引用類型和值類型

2019-11-17 03:23:17
字體:
供稿:網(wǎng)友

[CLR via C#]5.2 引用類型和值類型

  CLR支持兩種類型:引用類型和值類型。

  雖然FCL中大多數(shù)都是引用類型,但開發(fā)人員用的最多的還是值類型。引用類型總是在托管堆上分配的,C#的new操作符會返回對象的內(nèi)存地址——也就是指向?qū)ο髷?shù)據(jù)的內(nèi)存地址。  使用引用類型必須注意到一些性能問題,首先考慮一下事實:  1)內(nèi)存必須從托管堆上分配。  2)對上分配的每個對象都有一些額外的成員(比如前面提到過得"類型對象指針"和"同步塊索引"),這些成員必須初始化。  3)對象中的其他字節(jié)(為字段而設(shè))總是設(shè)為零。  4)從托管堆上分配一個對象時,可能強制執(zhí)行一次垃圾回收操作。  如果所有類型都是引用類型,應(yīng)用程序的性能會顯著下降。為了提升簡單的、常用的類型的性能,CLR提供了名為"值類型"的輕量型類型。  值類型的實例一般在線程棧上分配的(雖然也可作為字段嵌入一個引用類型的對象中)。在代表值類型的實例的一個變量中,并不包含一個指向?qū)嵗闹羔槨O喾矗兞恐邪藢嵗旧淼淖侄巍! ∮捎谧兞恳呀?jīng)包含了實例的字段,所以為了操作實例中的字段,不再需要提供一個指針。值類型的實例不受垃圾回收器的控制。因此,值類型的使用緩解了托管堆中的壓力,并減少了一個應(yīng)用程序在其生存期內(nèi)需要進(jìn)行的垃圾回收次數(shù)。  .NET Framework SDK文檔明確指出,在查看一個類型時,任何稱為"類"的類型都是引用類型。如System.Exception類、System.Random類等引用類型。文檔將所有值類型都成為結(jié)構(gòu)或枚舉。如System.Int32結(jié)構(gòu)、System.Boolean結(jié)構(gòu)等值類型。  所有值類型都必須從System.ValueType派生。所有枚舉類型都從System.Enum抽象類派生,而System.Enum又是從System.ValueType派生的。CLR和所有編程語言都給予枚舉特殊待遇,以后會提到。  所有值類型都是隱式密封的(sealed),目的是防止將一個值類型用于其他任何引用類型或值類型的基類型。  在托管代碼中,要由定義類型的開發(fā)人員決定在什么地方分配類型的實例,使用該類型的人對此并無控制權(quán)。  以下演示引用類型和值類型的區(qū)別:
//引用類型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 } 

  除非以下條件都能滿足,否則不應(yīng)該將一個類型聲明成值類型:

  1)類型具有基元類型的行為。  2)類型不需要從其他任何類型繼承  3)類型也不會派生出其他類型。  類型實例的大小應(yīng)該在考慮之列,因為默認(rèn)情況下,實參是以傳值方式傳遞的,這會造成對值類型實例中的字段進(jìn)行復(fù)制,從而影響性性能。同樣的,被定義為返回一個值類型的一個方法在返回時,實例中的字段會賦值到調(diào)用者分配的內(nèi)存中,從而影響性能。  所以,選用值類型還應(yīng)滿足:  1)類型的實例較小(約16字節(jié)或者更小)  2)類型的實例較大(大于16字節(jié)),但不作為方法的實參傳遞,也不從方法返回。  值類型的主要優(yōu)勢在于它們不作為對象在托管堆上分配。  值類型和引用類型的區(qū)別:  1)值類型對象有兩種表示形式:未裝箱(unboxed)和已裝箱(boxed)。引用類型總是處于已裝箱形式。  2)值類型是從System.ValueType派生的。該類型提供了與System.Object定義的相同的方法。然而,System.ValueType重寫了Equals方法和GetHashCode方法。由于這個默認(rèn)實現(xiàn)存在性能問題,所以定義自己的值類型時,應(yīng)該重寫Equals和GetHashCode方法,并提供它們的顯示實現(xiàn)。  3)值類型的所有方法都不能是抽象的,而且所有方法都是隱式密封(sealed)方法。  4)引用類型的變量包含的是堆上的一個對象的地址。默認(rèn)情況,在創(chuàng)建一個引用類型的變量時,它被初始化為null,表明引用類型的變量當(dāng)前不指向一個有效對象。相反,值類型初始化是,所有的成員都會初始化為0。由于值類型的變量不是指針,所以在訪問一個值類型時,不會拋出NullReferenceException異常。CLR確實提供了一個特殊的特性,能為值類型 添加"可空"標(biāo)識。如"int?"  5) 將一個值類型的變量賦給另一個值類型變量,會執(zhí)行一次逐字段復(fù)制。將引用類型賦給另一個引用類型時,只復(fù)制內(nèi)存地址。  6)由于為裝箱的值類型不再堆上分配,所以一旦定義了該類型的一個實例的方法不再處于活動狀態(tài),為他們分配的內(nèi)存就會被釋放。這意味著值類型的實例在其內(nèi)存被回收時,不會通過Finalize方法接收到一個通知。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 虞城县| 禄丰县| 平和县| 台前县| 霍山县| 织金县| 绥江县| 徐州市| 韶关市| 朝阳市| 始兴县| 锡林郭勒盟| 桃源县| 乌审旗| 九龙县| 大同县| 汨罗市| 南木林县| 泰顺县| 漾濞| 浙江省| 额敏县| 阿鲁科尔沁旗| 芒康县| 本溪| 昂仁县| 南部县| 天全县| 灵璧县| 襄城县| 吴川市| 五河县| 仙居县| 繁昌县| 六枝特区| 乐平市| 句容市| 呼玛县| 方山县| 麦盖提县| 珠海市|