1. 程式人生 > 程式設計 >詳解c# 強制轉換和型別轉換

詳解c# 強制轉換和型別轉換

由於 C# 是在編譯時靜態型別化的,因此變數在聲明後就無法再次宣告,或無法分配另一種型別的值,除非該型別可以隱式轉換為變數的型別。 例如,string 無法隱式轉換為 int。 因此,在將 i 宣告為 int 後,無法將字串“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)。

隱式轉換

對於內建數值型別,如果要儲存的值無需截斷或四捨五入即可適應變數,則可以進行隱式轉換。 對於整型型別,這意味著源型別的範圍是目標類型範圍的正確子集。 例如,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# 強制轉換和型別轉換的資料請關注我們其它相關文章!