初學c#經常為這幾種數據類型轉換方式而迷茫,為了徹底搞清它們之間的區別和優缺點,結合網上前輩總結的資料和自己的動手驗證,在此寫出來,一方面,為那些跟我有過相似經歷的朋友們搜索資料的時候能提供一點微小的幫助,另一方面,希望前輩們路過的時候指導一下,看哪里有不合適的地方。
眾所周知,C#是一門強類型語言,對類型要求比較嚴格,但是在一定的條件下是可以相互轉換的,如將int型數據轉換成double型數據。C#允許使用兩種轉換方式:隱式轉換和顯式轉換。
1、隱式轉換
隱式轉換就是系統默認的、不需要加以聲明就可以進行的轉換。隱式轉換不要求在源代碼中使用任何特殊語法,編譯器自動執行隱式強制轉換。在隱式轉換過程中,編譯器無需對轉換進行詳細檢查就能夠安全地執行轉換。隱式強制轉換也稱為“擴展轉換“,因為要將窄數據類型轉換為寬數據類型,且還將確保不會在轉換過程中丟失數據。(注意:(1)轉換前后的類型必須相兼容 (例如:int和double (2)、隱式數值轉換實際上就是從低精度的數值類型到高精度的數值類型的轉換,即小的類型轉大的類型)
int a = 10; double b = a;//隱式轉換
2、顯式轉換
顯式類型轉換,又叫強制類型轉換。與隱式轉換正好相反,顯式轉換需要用戶明確地指定轉換的類型。顯式轉換包括所有的隱式轉換,也就是說把任何系統允許的隱式轉換寫成顯式轉換的形式都是允許的。用()實現顯示轉換,這表示,把轉換的目標類型名放在要轉換的值之前的圓括號中。
long val = 30000; int i = (int)val;//顯式轉換
提醒:
(1)、顯式轉換可能會導致錯誤。進行這種轉換時編譯器將對轉換進行溢出檢測。如果有溢出說明轉換失敗,就表明源類型不是一個合法的目標類型。無法進行類型轉換。
(2)、強制類型轉換會造成數據精度丟失。
3、通過方法進行類型轉換
(1)、使用ToString()方法。所有類型都繼承了Object基類,所以都有ToString()這個方法(轉化成字符串的方法)。
int i=200; string s=i.ToString(); //這樣字符串類型變量s的值就是”200” 。
(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);
bool isSucess=int.TryParse("12", out i);//輸出值為12;True bool isSucess=int.TryParse("ss", out i);//輸出值為0;False bool isSucess=int.TryParse("", out i);//輸出值為0;False
(4)、通過Convert類進行轉換,Convert類中提供了很多轉換的方法。使用這些方法的前提是能將需要轉換的對象轉換成相應的類型,如果不能轉換則會報格式不對的錯誤(即前提為面上要過得去例如string類型的“666”可以轉換為整數型666,string類型的“666aaa”卻轉換不成整數型 )。
static void Main(string[] args) { float num1=82.26f; int integer,num2; string str,strdate; DateTime mydate=DateTime.New; //Convert類的方法進行轉換 integer=Convert.ToInt32(num1); str=Convert.ToString(num1); strdate=Convert.ToString(mydate); num2=Convert.ToInt32(mydate); Console.WriteLine("轉換為整型數據的值{0}",integer); Console.WriteLine("轉換為字符串{0},str"); Console.WriteLine("日期型數據轉換為字符串值為{0}",strdate); Console.ReadKey(); }
附:Convert類常用的類型轉換方法
方法 說明
Convert.ToInt32() 轉換為整型(int)
Convert.ToChar() 轉換為字符型(char)
Convert.ToString() 轉換為字符串型(string)
Convert.ToDateTime() 轉換為日期型(datetime)
Convert.ToDouble() 轉換為雙精度浮點型(double)
Conert.ToSingle() 轉換為單精度浮點型(float)
(5)、 實現自己的轉換,通過繼承接口IConventible或者TypeConventer類,從而實現自己的轉換。
注意:以Int類型為例,int.Parse,Convert.ToInt和int.TryParse的比較
【1】.參數和適用對象不同
int.Parse的參數數據類型只能是string類型,適用對象為string類型的數據
convert.toInt參數比較多,具體可以參見最下面的重載列表
int.TryParse的參數只能是只能是string類型,適用對象為string類型的數據
【2】.異常情況不同
異常主要是針對數據為null或者為""的情況
Convert.ToInt32 參數為 null 時,返回 0;Convert.ToInt32 參數為 "" 時,拋出異常;int.Parse 參數為 null 時,拋出異常。; int.Parse 參數為 "" 時,拋出異常。int.TryParse()方法比int.Parse()方法多了
一個異常處理,如果出現異常則返回false,並且將輸出參數返回0。
【3】.返回值不同
int.TryParse與int.Parse和Convert.ToInt 在返回值的不同是返回bool類型。獲取轉換后的值是通過out result這個參數獲取的。
4、使用AS操作符轉換
使用AS操作符轉換,但是AS只能用於引用類型和可為空的類型。使用as有很多好處,當無法進行類型轉換時,會將對象賦值為NULL,避免類型轉換時報錯或是出異常。C#拋出異常在進行捕獲異常並進行處理是很消耗資源的,如果只是將對象賦值為NULL的話是幾乎不消耗資源的(消耗很小的資源)。
5、裝箱和拆箱
裝箱和拆箱在值類型和引用類型之間架起了一座橋梁,使得任何 value-type 的值都可以轉換為 object 類型的值,反過來轉換也可以。
裝箱:裝箱是指將一個值類型的數據隱式地轉換成一個對象類型(object)的數據。執行裝箱操作時不可避免的要在堆上申請內存空間,並將堆棧上的值類型數據復制到申請的堆內存空間上,這肯定是要消耗內存和cpu資源的。注意:在執行裝箱轉換時,也可以使用顯式轉換。
int i = 0; object obj = i; //裝箱:值類型轉換為引用類型 int j = (int)obj; //拆箱:引用類型轉換為值類型
拆箱:拆箱是指將一個對象類型的數據顯式地轉換成一個值類型數據。拆箱過程是裝箱的逆過程,是將存儲在堆上的引用類型值轉換為值類型並賦給值類型變量。拆箱操作分為兩步:一是檢查對象實例,確保它是給定值類型的一個裝箱值;而是將該值從實例復制到值類型變量中。
裝箱拆箱注意事項:
裝箱操作可以隱式進行,但拆箱操作必須顯示。
在裝箱的時候,並不需要顯示類型轉換。但在拆箱時需要類型轉換。
這是因為在拆箱時對象可以被轉換為任何類型。
裝什么拆什么
裝箱就是要在托管堆重開辟空間,不但要裝數值而且還要裝類型
所以說裝什么拆什么,也就是用什么值類型裝箱,就要用什么值類型拆箱。
裝箱和拆箱都是要消耗內存和cpu資源的,也就造成效率降低,所以要盡量避免使用。
裝箱拆箱應用——定義方法
static void add(object i) { …… } static void Main(string[] args) { short s = 10; int i = 100; long l = 1000; add(s); add(i); add(l); }
注:可以理解為我定義一個object類型,好多小類型可以賦值過來。