因為 C# 在編譯階段以靜態方式輸入,所以在宣告變數之後,除非該類型隱含轉換成變數的類型,否則無法再次宣告或指派另一個類型的值。 例如, string
無法隱含地轉換成 int
。 因此,在宣告 i
為 int
之後,您無法將字串 「Hello」 指派給它,如下列程式代碼所示:
int i;
// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";
不過,有時候您可能需要將值複製到另一種類型的變數或方法參數。 例如,您可能有一個整數變數,您必須傳遞至參數類型為 double
的方法。 或者,您可能需要將類別變數指派給介面類型的變數。 這類作業稱為 類型轉換。 在 C# 中,您可以執行下列類型的轉換:
隱含轉換:不需要任何特殊語法,因為轉換一律會成功,而且不會遺失任何數據。 範例包括從較小到較大的整數型別轉換、從衍生類別轉換成基類,以及範圍轉換。
明確轉換(casts):明確轉換需要 轉換表達式。 當轉換可能導致資訊遺失或因其他原因可能失敗時,需要進行類型轉換。 一般範例包括將數值轉換成具有較少精確度或較小範圍的型別,以及將基類實例轉換成衍生類別。
使用者定義的轉換:使用者定義的轉換會使用特殊方法,您可以定義這些方法,在沒有基類衍生類別關聯性的自定義類型之間啟用明確和隱含轉換。 如需詳細資訊,請參閱使用者定義轉換運算子。
使用協助程式類別的轉換:若要在不相容的類型之間轉換,例如整數和 System.DateTime 物件,或十六進位字串和位元組陣列,您可以使用 System.BitConverter 類別、 System.Convert 類別和
Parse
內建數值類型的方法,例如 Int32.Parse。 如需詳細資訊,請參閱下列文章:
隱含轉換
針對內建數值類型,當要儲存的值可以放入變數時,可以進行隱含轉換,而不會遭到截斷或四捨五入。 對於整數型別,此限制表示來源類型的範圍是目標型別範圍的適當子集。 例如, long (64 位整數) 類型的變數可以儲存 int (32 位整數) 可以儲存的任何值。 在下列範例中,編譯程式會在將值指派給 num
之前,隱含地將右邊的 值long
轉換成類型bigNum
。
// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
如需所有隱含數值轉換的完整清單,請參閱內建數值轉換一文的隱含數值轉換一節。
針對參考型別,隱含轉換一律會從類別到其任何一個直接或間接基類或介面。 不需要特殊語法,因為衍生類別一律包含基類的所有成員。
Derived d = new Derived();
// Always OK.
Base b = d;
明確轉換
不過,如果沒有遺失信息的風險,就無法進行轉換,編譯程式會要求您執行稱為 轉換的明確轉換。 類型轉換是一種明確進行轉換的方法。 這表示您意識到數據可能會遺失,或者類型轉換可能會在運行時失敗。 若要執行轉換,請在您要轉換的表達式之前,以括號指定目的地類型。 下列程式會將 double 轉換成 int。若不進行這種轉換,程式將無法編譯。
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
Console.WriteLine(a);
// Output: 1234
如需支持明確數值轉換的完整清單,請參閱內建數值轉換一文的明確數值轉換一節。
針對參考型別,如果您需要從基底類型轉換成衍生型別,則需要進行顯式轉型:
參考型別之間的轉換作業不會變更基礎對象的運行時間類型;它只會變更做為該對象的參考所使用之值的型別。 如需詳細資訊,請參閱 多型。
執行時的類型轉換例外
在某些參考型別轉換中,編譯程式無法判斷轉換是否有效。 編譯時正確的轉換作業可能會在執行時失敗。 如下列範例所示,類型轉換在執行時失敗會導致拋出 InvalidCastException 。
Animal a = new Mammal();
Reptile r = (Reptile)a; // InvalidCastException at run time
明確將參數a
轉型為Reptile
,這樣的操作會做出危險的假設。 與其進行假設,不如檢查類型會更安全。 C# 提供 is
運算子,讓您能夠在實際執行轉換之前測試相容性。 如需詳細資訊,請參閱 如何使用模式比對和 as 和 is 運算元安全地轉換。