C#深入詳解[4.1 數據類型]
4.1? 數據類型
4.1.1? C#的數據類型
C#是強類型語言,因此每個變量和對象都必須具有聲明類型。C#開發語言的數據類型包括值類型和引用類型。
4.1.2? C#值類型
C#開發語言的值類型有15種,包括bool、byte、char、decimal、double、enum、float、int、long、sbyte、short、struct、uint、ulong和ushort。
4.1.2.1? C#值類型介紹——bool類型
1.bool類型的定義
bool關鍵字是System.Boolean的別名。它用于聲明變量來存儲布爾值true和false,可將布爾值賦給bool變量,也可以將計算為bool類型的表達式賦給bool變量。
功能說明:bool類型的定義。
程序清單4-1
using System;
public class MyClass
{
??? static void Main()
??? {
??????? bool J = true;
??????? char D = '0';
??????? Console.WriteLine(J);
??????? J = false;
??????? Console.WriteLine(J);
??????? bool abc = (D > 64 && D < 123);
??????? Console.WriteLine(abc);
??? }
}
運行結果如圖4-1所示。
圖4-1? bool類型的定義
2.bool類型的轉換
在C++中,bool類型的值可轉換為int類型的值,false等效于零值,而true等效于非零值。但是在C#語言中,不存在bool類型與其他類型之間的相互轉換。例如,下列if語句在C#中是非法的,而在C++中則是合法的:
int x = 123;
if (x)?? // 注意:在C#中此語句是錯誤的
{
??? printf("x is 非零值.");
}
若要測試int類型的變量,必須將該變量與一個值(例如零)進行顯式比較,如下所示:
int x = 123;
if (x != 0)?? // C#的判斷方式
{
??? Console.Write("The value of x is nonzero.");
}
功能說明:從鍵盤輸入一個字符,然后程序檢查輸入的字符是否是一個字母。如果輸入的字符是字母,則程序檢查是大寫還是小寫。這些檢查是使用IsLetter和IsLower(兩者均返回bool類型)來執行的。
程序清單4-2
using System;
public class BoolTest1
{
??? static void Main()
??? {
??????? Console.Write("請輸入一個字母: ");
??????? char c = (char)Console.Read();
??????? if (Char.IsLower(c))
??????? {
??????????????? Console.WriteLine("這個字符是小寫字母.");
??????? }
??????? else
??????? {
??????????????? Console.WriteLine("這個字符是大寫字母.");
??????? }
??? }
}
運行結果如圖4-2所示。
圖4-2? bool類型的轉換
4.1.2.2? 值類型介紹——byte類型
1.byte類型的定義
byte關鍵字代表一種整型,該類型的存儲值如表4-1所示。
表4-1? byte類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
byte |
0 - 255 |
無符號的 8 位整數 |
System.Byte |
2.byte類型的標識
如下例所示聲明并初始化byte類型的變量:
byte myByte = 15;
3.byte類型的轉換
存在從byte到short、ushort、int、uint、long、ulong、float、double或decimal的預定義隱式轉換。
注意
不能將更大存儲范圍的非文本數值類型隱式轉換為byte。
如:byte z = x + y;
以上的賦值語句將產生一個編譯錯誤,原因是賦值運算符右側的算術表達式在默認情況下的計算結果為int類型。
若要解決此問題,請使用強制轉換:
byte z = (byte)(x + y);
但是,在目標變量具有相同或更大的存儲時,使用下列語句是可能的:
int x = 25, y = 20;
int m = x + y;
long n = x + y;
4.1.2.3? 值類型介紹——char類型
1.char類型的定義
char關鍵字用于聲明表4-2所示范圍內的Unicode字符。Unicode字符是16位字符,用于表示世界上多數已知的書面語言。
表4-2 ?char類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
char |
U+0000 到 U+ffff |
16 位 Unicode |
System.Char |
2.char類型的標識
char類型的常數可以寫成字符、十六進制換碼序列或Unicode表示形式。你也可以顯式轉換整數字符代碼。以下所有語句均聲明了一個char變量并用字符Y將其初始化:
char char1 = 'Y';??????? // 字符
char char2 = '\x0050';?? // 16進制
char char3 = (char)89;?? // 準會整數字符代碼
char char4 = '\u0035';?? // Unicode
3.char類型的轉換
char可以隱式轉換為ushort、int、uint、long、ulong、float、double或decimal。但是,不存在從其他類型到char類型的隱式轉換。
4.1.2.4? 值類型介紹——decimal類型
1.decimal類型的定義
decimal關鍵字表示128位數據類型。同浮點型相比,decimal類型具有更高的精度和更小的范圍,這使它適合于財務和貨幣計算。該類型的存儲值如表4-3所示。
表4-3? decimal類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
decimal |
± 1.0 * 10e?28 至± 7.9 *10e28 |
28 到 29 位有效 |
System.Decimal |
2.decimal類型的標識
如果希望實數被視為decimal類型,請使用后綴m或M,例如:
decimal myMoney = 300.3m;
如果沒有后綴m,數字將被視為double類型,從而導致編譯器錯誤。
3.decimal類型的轉換
整型被隱式轉換為decimal,其計算結果為decimal。因此,可以用整數初始化十進制變量而不使用后綴,如下所示:
decimal myMoney = 300;
在浮點型和decimal類型之間不存在隱式轉換;因此,必須使用強制轉換在這兩種類型之間進行轉換,如下所示:
decimal myMoney = 99.8m;
double x = (double)myMoney;
myMoney = (decimal)x;
4.decimal類型的十進制輸出
可以通過使用String.Format方法或System.Console.Write方法(它調用String.Format())來格式化結果。指定貨幣格式時需要使用標準貨幣格式字符串“C”或“c”。
在此例中,同一個表達式中混合使用了decimal和int,計算結果為decimal類型。
如果試圖使用下面這樣的語句添加double和decimal變量:
double x = 8;
Console.WriteLine(d + x); // Error
將導致下列錯誤:
Operator '+' cannot be applied to operands of type 'double' and 'decimal'
功能說明:decimal類型的十進制輸出。
程序清單4-3
using System;
public class Decimal_Test
{
??? static void Main()
??? {
??????? decimal d = 5.6m;
??????? int y = 9;
??????? Console.WriteLine(d + y);??
??? }
}
輸出結果如圖4-3所示。
圖4-3? decimal類型的十進制輸出
功能說明:在此例中,輸出用貨幣格式字符串格式化。注意:其中x被舍入,因為其小數點位置超出了$0.99。而表示最大精確位數的變量y嚴格按照正確的格式顯示。
程序清單4-4
using System;
public class Format_decimal_Test
{
??? static void Main()
??? {
??????? decimal x = 0.999m;
??????? decimal y = 1234567890m;
??????? Console.WriteLine("My amount = {0:C}", x);
??????? Console.WriteLine("Your amount = {0:C}", y);
??? }
}
輸出結果如圖4-4所示。
圖4-4? 輸出用貨幣格式字符串格式化
4.1.2.5? 值類型介紹——double類型
1.double類型的定義
double關鍵字表示存儲64位浮點值的簡單類型,該類型的存儲值如表4-4所示。
表4-4? double類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
double |
± 5.0 × 10 - 324 到± 1.7 × 10308 |
15 到 16 位 |
System.Double |
2.double類型的標識
默認情況下,賦值運算符右側的實數被視為double。但是,如果希望整數被視為double,請使用后綴d或D,例如:
?? double x = 8D;
3.double類型的轉換
可在一個表達式中兼用數值整型和浮點型。在此情況下,整型將轉換為浮點型。根據以下規則計算表達式:
— 如果其中一個浮點類型為double,則表達式的計算結果為double類型,在關系表達式或布爾表達式中為bool類型。
— 如果表達式中不存在double類型,則表達式的計算結果為float類型,在關系表達式或布爾表達式中為bool類型。
浮點表達式可以包含下列值集:
— 正零和負零。
— 正無窮和負無窮。
— 非數字值(NaN)。
— 有限的非零值集。
功能說明:在下面的示例中,一個int、一個short、一個float和一個double相加,計算結果為double類型。
程序清單4-5
using System;
class double_Mixed_Test
{
??? static void Main()
??? {
??????? int i1 = 52;
??????? float f1 = 9.5f;
??????? short s1 = 9;
??????? double d1 = 4.2E+3;
??????? Console.WriteLine("數據總和等于: {0}", i1 + f1 + s1 + d1);
??? }
}
運行結果如圖4-5所示。
圖4-5? double類型的轉換
4.1.2.6? 值類型介紹——enum類型
1.enum類型的定義
enum關鍵字是一種由一組稱為枚舉數列表的命名常數組成的獨特類型。每種枚舉類型都有基礎類型,該類型可以是除char以外的任何整型。
注意
枚舉元素的默認基礎類型為int。
2.enum類型的標識
默認情況下,第一個枚舉數的值為0,后面每個枚舉數的值依次遞增1。例如:
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
此枚舉中,強制元素序列從1而不是0開始。例如:
?enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
注意
枚舉數的名稱中不能包含空白。
3.enum類型的轉換
基礎類型指定為每個枚舉數分配的存儲大小。但是,從enum類型到整型的轉換需要用顯式類型轉換來完成。例如,下面的語句通過使用強制轉換從enum轉換為int,將枚舉數Sun賦給int類型的變量:
int x = (int)Days.Sun;
4.enum類型進行可靠編程
如果其他開發人員將使用你的enum代碼,你需要提供相關說明,告訴開發人員將新元素添加到任何enum類型時,它們的代碼對應的響應是什么。
功能說明:在此例中,聲明了一個枚舉names。兩個枚舉數被顯式轉換為整數并賦給整型變量。
程序清單4-6
using System;
public class Enum_Test
{
??? enum names { mary = 8,tom, jack, jenefer };
??? static void Main()
??? {
??????? int x = (int)names.mary; int y = (int)names.jenefer;
??????? Console.WriteLine("mary = {0}", x);
??????? Console.WriteLine("jenefer = {0}", y);
??? }
}
運行結果如圖4-6所示。
圖4-6? enum類型進行可靠編程
4.1.2.7? 值類型介紹——float類型
1.float類型的定義
float關鍵字表示存儲32位浮點值的簡單類型,該類型的存儲值如表4-5所示。
表4-5? float類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
float |
± 1.5 × 10 - 45 to ± 3.4 × 1038 |
7 位 |
System.Single |
2.float類型的標識
默認情況下,賦值運算符右側的實數被視為double。因此,應使用后綴f或F初始化浮點型變量,如下所示:
float x = 3.5F;
注意
如果在以上聲明中不使用后綴,則會因為你試圖將一個double值存儲到float變量中而發生編譯錯誤。
3.float類型的轉換
可在一個表達式中兼用數值整型和浮點型。在此情況下,整型將轉換為浮點型。根據以下規則計算表達式:
— 如果其中一個浮點型為double,則表達式的計算結果為double類型,在關系表達式或布爾表達式中為bool類型。
— 如果表達式中不存在double類型,則表達式的計算結果為float類型,在關系表達式或布爾表達式中為bool類型。
浮點表達式可以包含下列值集:
— 正零和負零
— 正無窮和負無窮
— 非數字值(NaN)
— 有限的非零值集
功能說明:在下面的示例中,包含int、short和float類型的數學表達式得到一個float結果。請注意,表達式中沒有double。
程序清單4-7
using System;
class float_mixed_Test
{
??? static void Main()
??? {
??????? int x = 2;
??????? float y = 6.5f;
??????? short z = 11;
??????? Console.WriteLine("最后的結果是: {0}", x * y / z);
??? }
}
輸出結果如圖4-7所示。
圖4-7? float類型轉換
4.1.2.8? 值類型介紹——int類型
1.int類型的定義
int關鍵字表示一種整型,該類型的存儲值如表4-6所示。
表4-6? int類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
int |
- 2,147,483,648 到 2,147,483,647 |
有符號 32 位整數 |
System.Int32 |
2.int類型的標識
可以聲明并初始化int類型的變量,例如:
int i = 123;
注意
如果整數沒有后綴,則其類型為以下類型中可表示其值的第一個類型:int、uint、long、ulong。在此例中為int類型。
3.int類型的轉換
存在從int到long、float、double或decimal的預定義隱式轉換。例如:
float f = 133;
存在從sbyte、byte、short、ushort或char到int的預定義隱式轉換。例如,如果不進行強制轉換,下面的賦值語句將產生編譯錯誤。
long aLong = 42;
int i1 = aLong;?????? ?? // 這個語句是錯誤的,需要做強制轉換
int i2 = (int)aLong;? ? //經過強制轉換后, 表達式是正確的
注意
不存在從浮點型到int類型的隱式轉換。例如,除非使用顯式強制轉換,否則以下語句將生成一個編譯器錯誤:
int x = 5.0;???????? ??? // 這個表達式是錯誤的,不存在浮點型到int的隱形轉換
int y = (int)5.0;?? //強制轉換后,表達式是正確的
4.1.2.9? 值類型介紹——long類型
1.long類型的定義
long關鍵字表示一種整型,該類型的存儲值如表4-7所示。
表4-7? long類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
long |
- 9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
有符號 64 位整數 |
System.Int64 |
2.long類型的標識
可以聲明并初始化long類型的變量,例如:
long long1 = 4294967296;
注意
如果整數沒有后綴,則其類型為以下類型中可表示其值的第一個類型:int、uint、long、ulong。在上例中,它是long類型,因為它超出了uint的范圍。
還可以像下面這樣,在long類型中使用后綴L:
long long2 = 4294967296L;
當使用后綴L時,將根據整數的大小確定它的類型為long還是ulong。在此例中,它是long,因為它小于ulong的范圍的下限。
3.long類型的轉換
存在從long到float、double或decimal的預定義隱式轉換。其他情況下必須使用顯式轉換。例如,不使用顯式類型轉換時,下列語句將產生編譯錯誤:
int x = 6L;??????? //不可以從long到int的轉換
int x = (int)6L;?? //long類型到int類型必須經過強制轉換
存在從sbyte、byte、short、ushort、int、uint或char到long的預定義隱式轉換。
注意
不存在從浮點型到long類型的隱式轉換。
例如,除非使用顯式強制轉換,否則以下語句將生成一個編譯器錯誤:
long x =4.0;?????? ???// 不可以從浮點型到long的轉換
long y = (long)4.0;?? //必須強制轉換才可以
4.1.2.10? 值類型介紹——sbyte類型
1.sbyte類型的定義
sbyte關鍵字代表一種整型,該類型的存儲值如表4-8所示。
表4-8? sbyte類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
sbyte |
- 128 ~ 127 |
有符號的 8 位整數 |
System.Sbyte |
2.sbyte類型的標識
可如下例所示聲明并初始化sbyte類型的變量:
sbyte sbyte1 = 127;
注意
在以上聲明中,整數127從int隱式轉換為sbyte。如果整數超出了sbyte的范圍,將產生編譯錯誤。
3.sbyte類型的轉換
存在從sbyte到short、int、long、float、double或decimal的預定義隱式轉換。不能將存儲范圍更大的非文本數值類型隱式轉換為sbyte類型。
例如:
? sbyte x = 10, y = 20;
注意
不存在從浮點型到sbyte類型的隱式轉換。
例如,除非使用顯式強制轉換,否則以下語句將生成一個編譯器錯誤:
sbyte x = 3.0;???????? ??// 轉換錯誤
sbyte y = (sbyte)3.0;? ?// 強制轉換后,正確
4.1.2.11? 值類型介紹——short類型
1.short類型的定義
short關鍵字代表一種整型數據類型,該類型的存儲值如表4-9所示。
表4-9 ?short類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
short |
- 32 768~32 767 |
有符號的 16 位整數 |
System.Int16 |
2.short類型的標識
可如下例所示聲明并初始化short類型的變量:
short x = 32767;
注意
在以上聲明中,整數32 767從int隱式轉換為short。如果整數的長度超過了short存儲位置的大小,則將產生編譯錯誤。
3.short類型的轉換
存在從short到int、long、float、double或decimal的預定義隱式轉換。不能將存儲更大的非文本數值類型隱式轉換為short。
例如:
short x = 5, y = 12;
short z = x + y;??????????? ??????? // 轉換錯誤
short z = ( short )(x + y); ?????? // 強制轉換正確
short x = 5.0;???????? ???????????????? // 轉換錯誤
short y = (short)5.0;?? ?????????? // 強制轉換正確
注意
不存在從浮點型到short的隱式轉換。例如,除非使用顯式強制轉換,否則以下語句將生成一個編譯器錯誤。
4.1.2.12? 值類型介紹——struct類型
struct類型是一種值類型,通常用來封裝小型相關變量組,例如,商品的特征。下面的示例顯示了一個簡單的結構聲明。
public struct Book
{
??? public decimal price;???? //價格
??? public string title;????? //題目
??? public string author;???? //作者
}
結構還可以包含構造函數、常量、字段、方法、屬性、索引器、運算符、事件和嵌套類型,但如果同時需要上述幾種成員,則應當考慮改為使用類作為類型。
結構可以實現接口,但它們無法繼承另一個結構。因此,結構成員無法聲明為protected。
4.1.2.13? 值類型介紹——uint類型
1.uint類型的定義
uint關鍵字表示一種整型,該類型的存儲值如表4-10所示。
表4-10? uint類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
uint |
0 到 4 294 967 295 |
無符號 32 位整數 |
System.UInt32 |
2.uint類型的標識
可以聲明并初始化uint類型的變量,例如:
uint myUint = 4294967290;
注意
如果整數沒有后綴,則其類型為以下類型中可表示其值的第一個類型:int、uint、long、ulong。在此例中,它是uint。
uint uInt1 = 133;
還可以像下面這樣使用后綴u或U:
uint uInt2 = 133U;
3.uint類型的轉換
存在從uint到long、ulong、float、double或decimal的預定義隱式轉換。
例如:float myFloat = 4294967290;?? //轉換是正確的
注意
存在從byte、ushort或char到uint的預定義隱式轉換。否則必須使用顯式轉換。例如,如果不進行強制轉換,下面的賦值語句將產生編譯錯誤。
uint x = 5.0;??????????? //轉換錯誤,不支持浮點到uint的轉換
uint y = (uint)5.0;???? //強制轉換是正確的
4.1.2.14? 值類型介紹——ulong類型
1.ulong類型的定義
ulong關鍵字表示一種整型,該類型的存儲值如表4-11所示。
表4-11? ulong類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
ulong |
0~18 446 744 073 709 551 615 |
無符號 64 位整數 |
System.UInt64 |
2.ulong類型的標識
可以聲明并初始化ulong類型的變量,例如:
ulong uLong = 9223372036854775808;
注意
如果整數沒有后綴,則其類型為以下類型中可表示其值的第一個類型:int、uint、long、ulong。在上面的示例中,它是ulong類型。
還可根據以下規則使用后綴指定文字類型:
— 如果使用L或l,那么根據整數的大小,可以判斷出其類型為long還是ulong。
— 如果使用U或u,那么根據整數的大小,可以判斷出其類型為uint還是ulong。
— 如果使用UL、ul、Ul、uL、LU、lu、Lu或lU,則整數的類型為ulong。
例如,以下三個語句的輸出將為系統類型Uint64,此類型對應于別名ulong:
Console.WriteLine(9223372036854775808L.GetType());
Console.WriteLine(123UL.GetType());
Console.WriteLine((123UL + 456).GetType());
3.ulong類型的轉換
存在從ulong到float、double或decimal的預定義隱式轉換。
不存在從ulong到任何整型的隱式轉換。例如,不使用顯式類型轉換時,下列語句將產生編譯錯誤:
long long1 = 6UL;?? // 轉換錯誤,不存在從 ulong 到任何整型的隱式轉換
存在從byte、ushort、uint或char到ulong的預定義隱式轉換。
同樣,不存在從浮點型到ulong類型的隱式轉換。例如,除非使用顯式強制轉換,否則以下語句將生成一個編譯器錯誤:
ulong x = 5.0; // 轉換錯誤,不存在從浮點型到 ulong 類型的隱式轉換
ulong y = (ulong)5.0; // 強制轉換正確
4.1.2.15? 值類型介紹——ushort類型
1.ushort類型的定義
ushort關鍵字表示一種整數數據類型,該類型的存儲值如表4-12所示。
表4-12? ushort類型
類 ??? 型 |
范 ??? 圍 |
大 ??? 小 |
類 ??? 型 |
ushort |
0~65 535 |
無符號 16 位整數 |
System.UInt16 |
2.ushort類型的標識
可以聲明并初始化ushort類型的變量,例如:
ushort myShort = 65535;//超出范圍
注意
在以上聲明中,整數65 535從int隱式轉換為ushort。如果整數超出了ushort的范圍,將產生編譯錯誤。
3.ushort類型的轉換
存在從ushort到int、uint、long、ulong、float、double或decimal的預定義隱式轉換。
存在從byte或char到ushort的預定義隱式轉換。其他情況下必須使用顯式轉換。例如,請看以下兩個ushort變量x和y:
ushort x = 4, y = 13;
以下賦值語句將產生一個編譯錯誤,原因是賦值運算符右側的算術表達式在默認情況下的計算結果為int類型。
ushort z = x + y;?
若要解決此問題,請使用強制轉換:
ushort z = (ushort)(x + y);?? //使用強制轉換
但是,在目標變量具有相同或更大的存儲時,使用下列語句是可能的:
int m = x + y;
long n = x + y;
4.1.3? 引用類型包括的內容
引用類型的變量又稱為對象,可存儲對實際數據的引用。
C#的引用類型包括class(類)、delegate(委托)、interface(接口)、object、string組成,本章先介紹一下object引用類型,其他引用類型會在其他章節重點介紹。
C#引用類型——object類型
1.object類型的定義
在C#的統一類型系統中,所有類型包括預定義類型、用戶定義類型、引用類型和值類型等都是直接或間接從Object繼承的。可以將任何類型的值賦給object類型的變量。
裝箱和取消裝箱使值類型能夠被視為對象。對值類型來說,裝箱是將該值類型打包到Object引用類型的一個實例中,這使得值類型可以存儲于垃圾回收堆中。而取消裝箱則是將從對象中提取值類型。
功能說明:示例演示了object類型的變量如何接收任何數據類型的值,以及object類型的變量如何在.NET Framework中使用Object的方法。
程序清單4-8
using System;
class obj_Sample_Class
{
??? public int i = 10;
}
class MainClass
{
??? static void Main()
??? {
??????? object a;
??????? a = 100;
??????? Console.WriteLine(a);
??????? Console.WriteLine(a.GetType());
??????? Console.WriteLine(a.ToString());
??????? a = new obj_Sample_Class();
??????? obj_Sample_Class classRef;
??????? classRef = (obj_Sample_Class)a;
??????? Console.WriteLine(classRef.i);
??? }
}
運行結果如圖4-8所示。
圖4-8? object類型的定義
2.“裝箱”的概念
在C#的統一類型系統中,所有類型(預定義類型、用戶定義類型、引用類型和值類型)都是直接或間接從Object繼承的。將值類型的變量轉換為對象的過程稱為“裝箱”。
3.“取消裝箱”的概念
將對象類型的變量轉換為值類型的過程稱為“取消裝箱”。
4.C#做“裝箱”轉換工作
裝箱用于在垃圾回收堆中存儲值類型。裝箱是值類型到object類型或到此值類型所實現的任何接口類型的隱式轉換。對值類型裝箱會在堆中分配一個對象實例,并將該值復制到新的對象中。
請看以下值類型變量的聲明:
int i = 123;
以下語句對變量i隱式應用裝箱操作:
object o = i;? // 裝箱操作
此語句的結果是在堆棧上創建對象引用o,而在堆上則引用int類型的值。該值是賦給變量i的值類型值的一個副本。
功能說明:此示例通過裝箱將整數變量i轉換為對象o。該示例表明原始值類型和裝箱的對象使用不同的內存位置,因此能夠存儲不同的值。
程序清單4-9
using System;
class boxing_Test
{
??? static void Main()
??? {
??????? int i = 100;
??????? object o = i;? // 裝箱
??????? i = 200;
??????? System.Console.WriteLine("直接賦值的數據= {0}", i);
??????? System.Console.WriteLine("裝箱后的數據= {0}", o);
??? }
}
運行結果如圖4-9所示。
圖4-9? C#做“裝箱”轉換工作
5.C#做“裝箱取消”轉換工作
取消裝箱是從object類型到值類型或從接口類型到實現該接口的值類型的顯式轉換。取消裝箱操作包括:
— 檢查對象實例,確保它是給定值類型的一個裝箱值。
— 將該值從實例復制到值類型變量中。
以下語句同時說明了裝箱和取消裝箱操作:
int i = 123;????? // a value type
object o = i;???? // boxing
int j = (int) o;? // unboxing
注意
要在運行時成功取消裝箱值類型,被取消裝箱的項必須是對一個對象的引用,該對象是先前通過裝箱該值類型的實例創建的。嘗試對null或對不兼容值類型的引用進行取消裝箱操作,將導致InvalidCastException。
功能說明:下面的示例演示無效的取消裝箱及引發的InvalidCastException。使用try和catch,在發生錯誤時顯示錯誤信息。
程序清單4-10
using System;
class Unboxing_Test
{
??? static void Main()
??? {
??????? int i = 100;
??????? object o = i;? // 裝箱
??????? try
??????? {
??????????? int j = (short) o;? // 取消裝箱???????????
??????????? System.Console.WriteLine("取消裝箱成功.");
??????? }
?????? ?catch (System.InvalidCastException e)
??????? {
??????????? System.Console.WriteLine("{0} 取消裝箱異常.", e.Message);
??????? }
??? }
}
運行結果如圖4-10所示。
圖4-10? C#做“裝箱取消”轉換工作
如果將下列語句:
int j = (int) o;
功能說明:被取消裝箱的項必須是對一個對象的引用。
程序清單4-11
using System;
class Unboxing_Test
{
??? static void Main()
??? {
??????? int i = 100;
??????? object o = i;? // 裝箱
??????? try
??????? {
??????????? int j = (int)o;? // 取消裝箱???????????
??????????? System.Console.WriteLine("取消裝箱成功.");
??????? }
??????? catch (System.InvalidCastException e)
??????? {
??????????? System.Console.WriteLine("{0} 取消裝箱異常.", e.Message);
??????? }
??? }
}
運行結果如圖4-11所示。
圖4-11? 被取消裝箱的項是對一個對象的引用
posted on 2008-09-05 22:26 死神 閱讀(1261) 評論(0) 編輯 收藏 所屬分類: C#學習