轉型和型別轉換 (C# 程式設計手冊)
更新: 2008 年 7 月
因為 C# 在編譯時期採用靜態型別,所以變數在經過宣告之後,就無法再次宣告或用來儲存任何其他型別的值,除非該型別可以轉換為變數的型別。例如,整數和任意字串間不能轉換。因此,在您將 i 宣告為整數之後,便無法指派字串 "Hello" 給它,如下列程式碼中所示。
int i;
i = "Hello"; // Error: "Cannot implicitly convert type 'string' to 'int'"
不過,您有時可能需要將值複製到其他型別的變數或方法參數中。例如,您必須將整數變數傳遞至參數型別為 double 的方法。或者,您可能需要將類別變數指派給介面型別 (Interface Type) 的變數。此類作業稱為「型別轉換」(Type Conversion)。在 C# 中,您可以執行以下類型的轉換:
隱含轉換:不必使用特殊語法,因為這類轉換屬於型別安全轉換,而且不會遺失資料。這類範例包括從小型到大型整數型別的轉換,以及從衍生類別 (Derived Class) 到基底類別 (Base Class) 的轉換。
明確轉換 (轉型):明確轉換需要使用轉型運算子。來源與目的變數相容,但可能會遺失資料,因為目的變數的型別大小會小於來源變數 (或是基底類別的來源變數)。
使用者定義轉換:使用者定義轉換是由特殊方法執行,您可以定義這些特殊方法,以啟用自訂型別 (不具有基底類別與衍生類別的關聯性) 之間的明確和隱含轉換。如需詳細資訊,請參閱轉換運算子 (C# 程式設計手冊)。
使用 Helper 類別的轉換:為了在不相容型別 (例如整數與 System.DateTime 物件或十六進位字串與位元組陣列) 之間進行轉換,您可以使用 System.BitConverter 類別、System.Convert 類別和內建數字型別 (Numeric Type) 的 Parse 方法,例如 Int32.Parse。如需詳細資訊,請參閱 HOW TO:將位元組陣列轉換為 int (C# 程式設計手冊)、HOW TO:將 string 轉換為 int (C# 程式設計手冊) 和 HOW TO:在十六進位字串和數字型別間轉換 (C# 程式設計手冊)。
隱含轉換
對於內建數字型別,如果要儲存的值能完全符合變數需求而不需捨去或進位,則可進行隱含轉換。例如,longlong (C# 參考) 型別的變數 (8 個位元組整數) 可以儲存 intint (C# 參考) (32 位元電腦中的 4 個位元組) 能夠儲存的任何值。在下列範例中,編譯器會將右邊的值隱含轉換為 long 型別之後,才指派給 bigNum。
// Implicit conversion. num long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
如需隱含數值轉換的完整清單,請參閱隱含數值轉換表 (C# 參考)。
針對參考型別 (Reference Type),將類別轉換為其任何直接或間接基底類別或介面時,一律會使用隱含轉換。不必使用特殊語法,因為衍生類別一定包含基底類別的所有成員。
Derived d = new Derived();
Base b = d; // Always OK.
明確轉換
如果轉換可能會造成資料遺失,編譯器會要求您執行明確轉換,這稱為「轉型」(Cast)。轉型是明確告知編譯器您打算進行轉換而且知道可能會造成資料遺失的一種方式。若要執行轉型,請在要轉換的值或變數前面的括號內指定要轉換的目標型別。下列程式會將 doubledouble (C# 參考) 轉型成 intint (C# 參考)。若沒有進行轉型,就無法編譯程式。
class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
System.Console.WriteLine(a);
}
}
// Output: 1234
如需可用的明確數值轉換清單,請參閱明確數值轉換表 (C# 參考)。
針對參考型別,如果需要從基底型別轉換成衍生型別,就必須進行明確轉換:
// Create a new derived type.
Giraffe g = new Giraffe();
// Implicit conversion to base type is safe.
Animal a = g;
// Explicit conversion is required to cast
// back to derived type. Note: This will compile but
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe) a;
參考型別之間的轉型作業並不會變更基礎物件的執行階段型別,只會變更做為該物件參考之值的型別。如需詳細資訊,請參閱多型 (C# 程式設計手冊)。
執行階段發生的型別轉換例外狀況
對於有些參考型別轉換,編譯器無法判斷轉型是否有效。因此轉型作業編譯正確,但卻可能會在執行階段失敗。如下列範例所示,型別轉換 (Type Cast) 在執行階段失敗將導致擲回 InvalidCastException。
class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Reptile : Animal { }
class Mammal : Animal { }
class UnSafeCast
{
static void Main()
{
Test(new Mammal());
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
static void Test(Animal a)
{
// Cause InvalidCastException at run time
// because Mammal is not convertible to Reptile.
Reptile r = (Reptile)a;
}
}
C# 提供 is 和 as 運算子,讓您可在實際執行轉型之前先測試相容性。如需詳細資訊,請參閱 HOW TO:使用 as 和 is 運算子進行安全轉型 (C# 程式設計手冊)。
C# 語言規格
如需轉型和型別轉換的詳細資訊,請參閱 C# 語言規格中的下列章節:
7.6.6 轉型運算式
6.1 隱含轉換
6.2 明確轉換
請參閱
工作
HOW TO:將 string 轉換為 int (C# 程式設計手冊)
概念
參考
變更記錄
日期 |
記錄 |
原因 |
---|---|---|
2008 年 7 月 |
在簡介和其他地方補充內容。 |
內容 Bug 修正。 |