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

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

int i;

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

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

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

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

  • 使用者定義的轉換:使用者定義的轉換是透過特殊方法所執行,而您可以定義特殊方法來啟用沒有基底類別/衍生類別關聯性之自訂類型間的明確和隱含轉換。 如需詳細資訊,請參閱使用者定義轉換運算子

  • 使用協助程式類別轉換:若要轉換不相容類型 (例如,整數和 System.DateTime 物件,或十六進位字串和位元組陣列),您可以使用 System.BitConverter 類別、System.Convert 類別,以及內建數字類型的 Parse 方法 (例如,Int32.Parse)。 如需詳細資訊,請參閱 如何將位元組陣列轉換成 int如何將字串轉換成數位,以及如何 在十六進位字串和數數值型別之間轉換

隱含的轉換

針對內建數字類型,如果要儲存的值可以放入變數中,而不需進行截斷或四捨五入,則可以進行隱含轉換。 針對整數型別,這表示來源型別的範圍是目標型別範圍的適當子集。 例如,型別為 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 參數,因此會明確地將 引數 aReptile 轉換成 ,以產生危險假設。 比較安全,不要進行假設,而是檢查類型。 C# 提供 is 運算子,可讓您先測試相容性,再實際執行轉換。 如需詳細資訊,請參閱 如何使用模式比對和 as 和 is 運算子安全地轉換

C# 語言規格

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

另請參閱