轉型和類型轉換 (C# 程式設計指南)

因為 C# 在編譯時期是靜態類型,所以在宣告變數之後,除非該類型隱含轉換成變數的類型,否則無法再次宣告或指派另一個類型的值。 例如, string 無法隱含地轉換成 int。 因此,在宣告 iint之後,您無法將字串 「Hello」 指派給它,如下列程式代碼所示:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

不過,您有時可能需要將值複製至另一種類型的變數或方法參數。 例如,您的整數變數可能需要傳遞給參數類型為 double 的方法。 或者,您可能需要將類別變數指派給介面類型的變數。 這些類型的作業稱為「類型轉換」。 在 C# 中,您可以執行下列類型的轉換:

  • 隱含轉換:不需要任何特殊語法,因為轉換一律會成功,而且不會遺失任何數據。 範例包括從較小到較大整數型別的轉換,以及從衍生類別到基底類別的轉換。

  • 明確轉換 (強制型轉):明確轉換需要強制型轉運算式。 如果資訊可能會在轉換時遺失,或轉換因其他原因而失敗,則需要轉換。 一般範例包括將數字轉換為較少有效位數或較小範圍的類型,以及將基底類別執行個體轉換為衍生類別。

  • 使用者定義的轉換:使用者定義的轉換會使用特殊方法,您可以定義這些方法,在沒有基類衍生類別關聯性的自定義類型之間啟用明確和隱含轉換。 如需詳細資訊,請參閱使用者定義轉換運算子

  • 使用協助程式類別轉換:若要轉換不相容類型 (例如,整數和 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。程式不會在沒有轉換的情況下編譯。

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

如需受支援明確數值轉換的完整清單,請參閱內建數值轉換一文的明確數值轉換一節。

針對參考型別,如果您需要將基底類型轉換為衍生類型,則需要明確轉換︰

// 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 will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

參考型別之間的轉換作業不會變更基礎對象的運行時間類型;它只會變更做為該對象的參考所使用之值的型別。 如需詳細資訊,請參閱多型

執行階段的類型轉換例外狀況

在某些參考型別轉換中,編譯程式無法判斷轉換是否有效。 轉換作業可以在運行時間正確編譯失敗。 如下列範例所示,在執行時間失敗的類型轉換會導致 InvalidCastException 擲回 。

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "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)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

Test 方法具有 Animal 參數,因此明確地將引數 a 強制型轉成 Reptile 會使其成為一個危險的假設動作。 不要進行假設,而是檢查類型更安全。 C# 提供 is 運算子,可讓您先測試相容性,再實際執行轉換。 如需詳細資訊,請參閱如何使用模式比對以及 as 和 is 運算子進行安全轉換

C# 語言規格

如需詳細資訊,請參閱 C# 語言規格轉換一節。

另請參閱