程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> [CLR via C#]5.2 基元類型

[CLR via C#]5.2 基元類型

編輯:C#入門知識

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

  雖然FCL中大多數都是引用類型,但開發人員用的最多的還是值類型。引用類型總是在托管堆上分配的,C#的new操作符會返回對象的內存地址——也就是指向對象數據的內存地址。   使用引用類型必須注意到一些性能問題,首先考慮一下事實:   1)內存必須從托管堆上分配。   2)對上分配的每個對象都有一些額外的成員(比如前面提到過得"類型對象指針"和"同步塊索引"),這些成員必須初始化。   3)對象中的其他字節(為字段而設)總是設為零。   4)從托管堆上分配一個對象時,可能強制執行一次垃圾回收操作。   如果所有類型都是引用類型,應用程序的性能會顯著下降。為了提升簡單的、常用的類型的性能,CLR提供了名為"值類型"的輕量型類型。   值類型的實例一般在線程棧上分配的(雖然也可作為字段嵌入一個引用類型的對象中)。在代表值類型的實例的一個變量中,並不包含一個執行實例的指針。相反,變量中包含了實例本身的字段。   由於變量已經包含了實例的字段,所以為了操作實例中的字段,不再需要提供一個指針。值類型的實例不受垃圾回收器的控制。因此,值類型的使用緩解了托管堆中的壓力,並減少了一個應用程序在其生存期內需要進行的垃圾回收次數。   .NET Framework SDK文檔明確指出,在查看一個類型時,任何成為"類"的類型都是引用類型。如System.Exception類、System.Random類等引用類型。文檔將所有值類型都成為結構或枚舉。如System.Int32結構、System.Boolean結構等值類型。   所有值類型都必須從System.ValueType派生。所有枚舉類型都從System.Enum抽象類派生,而System.Enum又是從System.ValueType派生的。CLR和所有編程語言都給予枚舉特殊待遇,以後會提到。   所有值類型都是隱式密封的(sealed),目的是防止將一個值類型用於其他任何引用類型或值類型的基類型。   在托管代碼中,要由定義類型的開發人員決定在什麼地方分配類型的實例,使用該類型的人對此並無控制權。   以下演示引用類型和值類型的區別:

  Main(=  SomeRef();     
    SomeVal v1 =  SomeVal();     
    r1.x = = 
    Console.WriteLine(v1.x);                
=== = 
    Console.WriteLine(r2.x);                
    Console.WriteLine(v1.x);                
    Console.WriteLine(v2.x);                
} 

  1)類型具有基元類型的行為。   2)類型不需要從其他任何類型繼承   3)類型也不會派生出其他類型。       類型實例的大小應該在考慮之列,因為默認情況下,實參是以傳值方式傳遞的,這會造成對值類型實例中的字段進行復制,從而影響性性能。同樣的,被定義為返回一個值類型的一個方法在返回時,實例中的字段會賦值到調用者分配的內存中,從而影響性能。   所以,選用值類型還應滿足:   1)類型的實例較小(約16字節或者更小)   2)類型的實例較大(大於16字節),但不作為方法的實參傳遞,也不從方法返回。   值類型的主要優勢在於它們不作為對象在托管堆上分配。   值類型和引用類型的區別:   1)值類型對象有兩種表示形式:未裝箱(unboxed)和已裝箱(boxed)。引用類型總是處於已裝箱形式。   2)值類型是從System.ValueType派生的。該類型提供了與System.Object定義的相同的方法。然而,System.ValueType重寫了Equals方法和GetHashCode方法。由於這個默認實現存在性能問題,所以定義自己的值類型時,應該重寫Equals和GetHashCode方法,並提供它們的顯示實現。   3)值類型的所有方法都不能是抽象的,而且所有方法都是隱式密封(sealed)方法。   4)引用類型的變量包含的是堆上的一個對象的地址。默認情況,在創建一個引用類型的變量時,它被初始化為null,表明引用類型的變量當前不指向一個有效對象。相反,值類型初始化是,所有的成員都會初始化為0。由於值類型的變量不是指針,所以在訪問一個值類型時,不會拋出NullReferenceException異常。CLR確實提供了一個特殊的特性,能為值類型 添加"可空"標識。如"int?"   5)  將一個值類型的變量賦給另一個值類型變量,會執行一次逐字段復制。將引用類型賦給另一個引用類型時,只復制內存地址。   6)由於為裝箱的值類型不再堆上分配,所以一旦定義了該類型的一個實例的方法不再處於活動狀態,為他們分配的內存就會被回收。        

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved