數據類型在一定的條件下是可以相互轉換的,如將int型數據轉換成double型數據。C#允許使用兩種轉換方式:隱式轉換和顯式轉換。
1、隱式轉換
隱式轉換:從類型A到類型B的轉換可以在所有情況下進行,執行轉換的規則非常簡單,可以讓編譯器執行轉換。
隱式轉換不需要做任何工作,也不需要另外編寫代碼。如將int型數據轉換成double型數據:
int a = 10; double b = a;//隱式轉換
隱式轉換規則是:任何類型A,只要其取值范圍完全包含在類型B的取值范圍內,就可以隱式轉換為類型B。基於這個轉換規則,C#的隱式轉換不會導致數據丟失。需要注意的是我們最常用的簡單類型bool和string沒有隱式轉換。
2、顯式轉換
顯式轉換:從類型A到類型B的轉換只能在某些情況下進行,轉換規則比較復雜,應進行某種類型的額外處理。顯式轉換又叫強制類型轉換,顯式轉換需要用戶明確的指定轉換類型。如將double類型數據轉換成int類型數據:
double c = 10.5; int d = (int)c;//顯示轉換
提醒:
(1)、顯式轉換可能會導致錯誤。進行這種轉換時編譯器將對轉換進行溢出檢測。如果有溢出說明轉換失敗,就表明源類型不是一個合法的目標類型。無法進行類型轉換。
(2)、強制類型轉換會造成數據丟失,如上面的例子中,最終得到的d值為10。
3、通過方法進行類型轉換
(1)、使用ToString()方法。所有類型都繼承了Object基類,所以都有ToString()這個方法(轉化成字符串的方法)。
(2)、通過int.Parse()方法轉換,參數類型只支持string類型。注意:使用該方法轉換時string的值不能為為NULL,不然無法通過轉換;另外string類型參數也只能是各種整型,不能是浮點型,不然也無法通過轉換 (例如int.Parse("2.0")就無法通過轉換)。
int i; i = int.Parse("100");
(3)、通過int.TryParse()方法轉換,該轉換方法與int.Parse()轉換方法類似,不同點在於int.Parse()方法無法轉換成功的情況該方法能正常執行並返回0。也就是說int.TryParse()方法比int.Parse()方法多了一個異常處理,如果出現異常則返回false,並且將輸出參數返回0。
int i; string s = null; int.TryParse(s,out i);
(4)、通過Convert類進行轉換,Convert類中提供了很多轉換的方法。使用這些方法的前提是能將需要轉換的對象轉換成相應的類型,如果不能轉換則會報格式不對的錯誤。注意:使用Convert.ToInt32(double value)時,如果 value 為兩個整數中間的數字,則返回二者中的偶數;即 4.5 轉換為 4,而 5.5 轉換為 6。
(5)、實現自己的轉換,通過繼承接口IConventible或者TypeConventer類,從而實現自己的轉換。
4、使用AS操作符轉換
使用AS操作符轉換,但是AS只能用於引用類型和可為空的類型。使用as有很多好處,當無法進行類型轉換時,會將對象賦值為NULL,避免類型轉換時報錯或是出異常。C#拋出異常在進行捕獲異常並進行處理是很消耗資源的,如果只是將對象賦值為NULL的話是幾乎不消耗資源的(消耗很小的資源)。
5、裝箱和拆箱
裝箱和拆箱在值類型和引用類型之間架起了一座橋梁,使得任何 value-type 的值都可以轉換為 object 類型的值,反過來轉換也可以。
裝箱:裝箱是指將一個值類型的數據隱式地轉換成一個對象類型(object)的數據。執行裝箱操作時不可避免的要在堆上申請內存空間,並將堆棧上的值類型數據復制到申請的堆內存空間上,這肯定是要消耗內存和cpu資源的。注意:在執行裝箱轉換時,也可以使用顯式轉換。
拆箱:拆箱是指將一個對象類型的數據顯式地轉換成一個值類型數據。拆箱過程是裝箱的逆過程,是將存儲在堆上的引用類型值轉換為值類型並賦給值類型變量。拆箱操作分為兩步:一是檢查對象實例,確保它是給定值類型的一個裝箱值;而是將該值從實例復制到值類型變量中。
裝箱和拆箱都是要消耗內存和cpu資源的,也就造成效率降低,所以要盡量避免使用。