C#中有兩種類型:值類型(value type)和引用類型(reference type)。值類型變量直接包括它們的數據,而引用類型變量存儲的是它們的數據引用,後者被認為是對象。對於引用類型,有可能兩個變量引用相同的對象,因此對其中一個變量的操作可能影響另一個對象引用的對象。對於值類型,每個變量都有自己的數據拷貝,因此對一個變量的操作不可能影響其他變量(ref和out參數變量例外)。
C#的值類型進一步劃分為簡單類型(simple type)、枚舉類型(enum type)和結構類型(struct type);C#的引用類型進一步劃分為類類型(class type)、接口類型(interface type)、數組類型(array type)和委托類型(delegate type)。
表1.1為整個C#類型系統的概述。
表1.1 C#類型系統的概述
類 別描 述值類型簡單類型有符號整型:sbyte,short,int,long無符號整型:byte,ushort,uint,ulongUnicode字符:charIEEE浮點型:float,double高精度小數:decimal布爾型:bool枚舉類型用戶自定義類型enum E{…}結構類型用戶自定義類型struct S{…}引用類型類類型所有其他類型的最終基類:objectUnicode字符串:string用戶自定義類型class C{…}接口類型用戶自定義類型interface I{…}數組類型單維與多維數組,例如,int[]與int[,]委托類型用戶自定義類型delegate T D(…)8個整型類型分別支持8位、16位、32位和64位整數的有符號或者無符號格式。
兩個浮點類型,float和double,分別用32位單精度和64位雙精度的IEEE754格式表示。
decimal是128位的數據類型,適合財金和貨幣方面的計算。
C#的bool類型用於表示布爾值——true或者false。
在C#中,字符和字符串的處理使用Unicode編碼。char類型表示16位的Unicode編碼單元,string類型表示16位的Unicode編碼單元的序列。
表1.2總結了C#的數值類型。
表1.2 C#的數值類型
類 別位 數類 型范圍/精度有符號整型8sbyte-128~12716short-32 768~32 76732int-2 147 483 648~2 147 483 64764long-9 223 372 036 854 775 808~9 223 372 036 854 775 807無符號整型8byte0~25516ushort0~6553532uint0~4 294 967 29564ulong0~18 446 744 073 709 551 615浮點型32float1.5×10-45~3.4×1038,7位精度64double5.0×10-324~1.7×10308,15位精度Decimal128decimal1.0×10-28~7.9×1028,28位精度
C#程序使用類型聲明創建新類型。類型聲明指定新類型的名字和成員。有5種C#類型可由用戶自定義:類類型、結構類型、接口類型、枚舉類型和委托類型。
l 類類型定義了一個數據結構,它包括數據成員(字段)和函數成員(方法、屬性及其他)。類類型支持繼承和多態,即派生類能夠擴展和特殊化基類的機制。
l 結構類型與類類型相似,表示帶有數據成員和函數成員的結構。然而,與類類型不同的是,結構是值類型,不需要堆分配。結構不支持用戶指定的繼承,所有的結構類型隱式地繼承類型object。
l 接口類型定義了一個約定,作為一組函數成員命名的集合。實現接口的類或結構必須提供接口函數成員的實現。接口可能從多個基接口繼承而來,類或結構也可能實現多個接口。
l 枚舉類型是帶有命名常量的獨特類型。每個枚舉類型有一個底層的類型,它必須是8個整型類型之一。枚舉類型的值集與底層類型的值集相同。
l 委托類型通過特定的參數列表和返回類型表示對方法的引用。委托將方法處理為實體,實體能夠賦值給變量,並且當做參數傳遞。委托類似於某些程序語言中的方法指針,不同之處在於,委托是面向對象的,並且是類型安全的。
C#支持任何類型的一維和多維數組。不同於其他類型,數組類型在它們被使用前不必聲明。事實上,數組類型的構造是由某個類型名加上方括號。例如,int[]是int的一維數組,int[,]是int的二維數組,而int[][]是int的一維數組的一維數組。
C#的類型系統是統一的,這樣任何類型的值都能夠被處理成對象。C#中每一個類型直接或者間接從object類繼承而來,並且object是所有類型最終的基類。值類型的值可以通過執行裝箱(boxing)和取消裝箱(unboxing)的操作處理為對象。在下面的示例中,int被轉換為object,然後又轉回到int。
using System; class Test { static void Main(){ int i=123; object o=i; //裝箱 int j=(int)o; //取消裝箱 } }
當值類型的值被強制類型轉換為object時,就會分配持有該值的對象實例(也稱為“箱子”),並且值也被拷貝到那個箱子裡。相反地,當object引用被強制類型轉換為值類型時,要檢查這個引用類型是否是當前值類型的箱子,如果是的話,箱子中的值就會被拷貝出來。
C#統一的類型系統意味著值類型能夠“按需”轉換為對象。由於這種統一性,使用object類型的通用類庫,例如.NET框架中的集合類,能夠通過引用類型和值類型使用。
C#中存在幾種變量,包括字段、數組元素、局部變量和參數。變量表示了存儲的位置,並且每一個變量都有一個類型,以決定什麼樣的值能夠存入變量中,如表1.3所示。
表1.3 C#的變量
變量類型可能的內容值類型值類型的值objectnull引用、任何引用類型的對象引用或任何值類型裝箱值的引用類類型null引用、該類類型實例的引用或由該類類型派生類的實例的引用接口類型null引用、實現該接口的類類型實例的引用或實現該接口的值類型裝箱值的引用數組類型null引用、該數組類型實例的引用或兼容數組類型實例的引用委托類型null引用或該委托類型實例的引用