C# 類(lèi)型轉(zhuǎn)換時(shí)需要注意的地方
一、類(lèi)型轉(zhuǎn)換的種類(lèi)
隱式類(lèi)型轉(zhuǎn)換 - 這些轉(zhuǎn)換是 C# 默認(rèn)的以安全方式進(jìn)行的轉(zhuǎn)換, 不會(huì)導(dǎo)致數(shù)據(jù)丟失。例如,從小的整數(shù)類(lèi)型轉(zhuǎn)換為大的整數(shù)類(lèi)型,從派生類(lèi)轉(zhuǎn)換為基類(lèi)。
顯式類(lèi)型轉(zhuǎn)換 - 顯式類(lèi)型轉(zhuǎn)換,即強(qiáng)制類(lèi)型轉(zhuǎn)換。顯式轉(zhuǎn)換需要強(qiáng)制轉(zhuǎn)換運(yùn)算符,而且強(qiáng)制轉(zhuǎn)換會(huì)造成數(shù)據(jù)丟失。
二、顯式轉(zhuǎn)換注意事項(xiàng)
顯式轉(zhuǎn)換:通過(guò)用戶使用預(yù)定義的函數(shù)顯式完成的,顯式轉(zhuǎn)換需要強(qiáng)制轉(zhuǎn)換運(yùn)算符。
轉(zhuǎn)換類(lèi)型的范圍大小和從屬關(guān)系和隱式轉(zhuǎn)換相反。顯式轉(zhuǎn)換可能會(huì)導(dǎo)致數(shù)據(jù)出錯(cuò),或者轉(zhuǎn)換失敗,甚至無(wú)法編譯成功。
實(shí)例:
double dnum = 100.1;
int ifromd = (int)dnum; //double類(lèi)型顯式轉(zhuǎn)換轉(zhuǎn)為int類(lèi)型
Class1 c11 = new Class1();
Class2 c22 = c11 as Class2; //使用as進(jìn)行顯式轉(zhuǎn)換
Console.WriteLine(c22 is Class1);
Console.WriteLine(c22 is Class2);
運(yùn)行結(jié)果:
FALSE
FALSE
三、類(lèi)型之間的轉(zhuǎn)換 - Convert 和 Parse
string locstr = 123.ToString();
//如果要將"locstr"轉(zhuǎn)成整型數(shù)
//方法一: 用 Convert
int i = Convert.ToInt16(locstr);
//方法二: 用 Parse
int ii = int.Parse(locstr);
1.int.TryParse(string s,out int i)
該方式也是將數(shù)字內(nèi)容的字符串轉(zhuǎn)換為int類(lèi)型,但是該方式比int.Parse(string s) 好一些,它不會(huì)出現(xiàn)異常,最后一個(gè)參數(shù)result是輸出值,如果轉(zhuǎn)換成功則輸出相應(yīng)的值,轉(zhuǎn)換失敗則輸出0。
class test
{
? ?static void Main(string[] args)
? ?{
? ? ? ?string s1="abcd";
? ? ? ?string s2="1234";
? ? ? ?int a,b;
? ? ? ?bool bo1=int.TryParse(s1,out a);
? ? ? ?Console.WriteLine(s1+" "+bo1+" "+a);
? ? ? ?bool bo2=int.TryParse(s2,out b);
? ? ? ?Console.WriteLine(s2+" "+bo2+" "+b);
? ?}
}
結(jié)果輸出:
abcd False 0
1234 True 1234
C# 中對(duì) double 類(lèi)型的數(shù)據(jù)取整,可以使用 convert.toint32() 方法,也可使用 int 強(qiáng)制轉(zhuǎn)換為整數(shù),使用 int 時(shí)并不存在四舍五入的情況,而是直接將后面的小數(shù)位數(shù)丟掉。比如:
class Program
{
? ?static void Main(string[] args)
? ?{
? ? ? ?double a = 1.35;
? ? ? ?double b = 1.65;
? ? ? ?int a1 = Convert.ToInt32(a);
? ? ? ?int a2 = (int)(a);
? ? ? ?int b1 = Convert.ToInt32(b);
? ? ? ?int b2 = (int)(b);
? ? ? ?Console.WriteLine("{0}使用convert方法轉(zhuǎn)化的結(jié)果為:{1}",a,a1);
? ? ? ?Console.WriteLine("{0}使用int強(qiáng)制轉(zhuǎn)換的結(jié)果為:{1}",a,a2);
? ? ? ?Console.WriteLine("{0}使用convert方法轉(zhuǎn)化的結(jié)果為:{1}", b, b1);
? ? ? ?Console.WriteLine("{0}使用int強(qiáng)制轉(zhuǎn)換的結(jié)果為:{1}", b, b2);
? ? ? ?Console.ReadKey();
? ?}
}
程序運(yùn)行結(jié)果如下:
? ? 1.35使用convert方法轉(zhuǎn)化的結(jié)果為:1
? ? 1.35使用int強(qiáng)制轉(zhuǎn)換的結(jié)果為:1
? ? 1.65使用convert方法轉(zhuǎn)化的結(jié)果為:2
? ? 1.65使用int強(qiáng)制轉(zhuǎn)換的結(jié)果為:1
2.Convert.ToInt32() 與 int.Parse() 的區(qū)別
沒(méi)搞清楚 Convert.ToInt32 和 int.Parse() 的細(xì)微區(qū)別時(shí)千萬(wàn)別亂用,否則可能會(huì)產(chǎn)生無(wú)法預(yù)料的結(jié)果,舉例來(lái)說(shuō):假如從 url 中取一個(gè)參數(shù) page 的值,我們知道這個(gè)值是一個(gè) int,所以即可以用 Convert.ToInt32(Request.QueryString["page"]),也可以用 int.Parse(Request.QueryString["page"]),但是如果 page 這個(gè)參數(shù)在 url 中不存在,那么前者將返回 0,0 可能是一個(gè)有效的值,所以你不知道 url 中原來(lái)根本就沒(méi)有這個(gè)參數(shù)而繼續(xù)進(jìn)行下一下的處理,這就可能產(chǎn)生意想不到的效果,而用后一種辦法的話沒(méi)有 page 這個(gè)參數(shù)會(huì)拋出異常,我們可以捕獲異常然后再做相應(yīng)的處理,比如提示用戶缺少參數(shù),而不是把參數(shù)值當(dāng)做 0 來(lái)處理。
(1) 這兩個(gè)方法的最大不同是它們對(duì) null 值的處理方法: Convert.ToInt32(null) 會(huì)返回 0 而不會(huì)產(chǎn)生任何異常,但 int.Parse(null) 則會(huì)產(chǎn)生異常。
從運(yùn)行報(bào)錯(cuò)的角度講,(int) 強(qiáng)制轉(zhuǎn)換和 int.Parse() 都不能接受 NULL;Convert.ToInt32() 其實(shí)是在轉(zhuǎn)換前先做了一個(gè)判斷,參數(shù)如果為 NULL,則直接返回 0,否則就調(diào)用 int.Parse() 進(jìn)行轉(zhuǎn)換,int.TryParse() 其實(shí)是對(duì) int.Parse() 做了一個(gè)異常處理,如果出現(xiàn)異常則返回 false,并且將輸出參數(shù)返回 0;
(2) 對(duì)數(shù)據(jù)進(jìn)行四舍五入時(shí)候的區(qū)別
a. Convert.ToInt32(double value) 如果 value 為兩個(gè)整數(shù)中間的數(shù)字,則返回二者中的偶數(shù);即 3.5 轉(zhuǎn)換為 4,4.5 轉(zhuǎn)換為 4,而 5.5 轉(zhuǎn)換為 6。不過(guò) 4.6 可以轉(zhuǎn)換為 5,4.4 轉(zhuǎn)換為 4 。
b. int.Parse("4.5") 直接報(bào)錯(cuò):"輸入字符串的格式不正確"。
c. int(4.6) = 4 Int 轉(zhuǎn)化其他數(shù)值類(lèi)型為 Int 時(shí)沒(méi)有四舍五入,強(qiáng)制轉(zhuǎn)換。
(3) 對(duì)被轉(zhuǎn)換類(lèi)型的區(qū)別 int.Parse 是轉(zhuǎn)換 String 為 int, Convert.ToInt32 是轉(zhuǎn)換繼承自 Object 的對(duì)象為 int 的(可以有很多其它類(lèi)型的數(shù)據(jù))。你得到一個(gè) object 對(duì)象, 你想把它轉(zhuǎn)換為 int, 用 int.Parse 就不可以, 要用 Convert.ToInt32。
Convert.ToInt32() 可以為多種類(lèi)型(例出數(shù)字類(lèi)型外 bool,DateTime 等),int.TryParse() 和 int.Parse() 只能是整型字符串類(lèi)型(即各種整型 ToString() 之后的形式,不能為浮點(diǎn)型,否則 int.Parse() 就會(huì)出現(xiàn)輸入的字符串格式不正確的錯(cuò)誤,int.TryParse() 也會(huì)返回 false,輸出參數(shù)為 0 ,(int)只能是數(shù)字類(lèi)型(例 float,int,uint等)。
(4)關(guān)于溢出,將大的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為小的數(shù)據(jù)類(lèi)型時(shí) Convert.ToInt32() 和 int.Parse() 都會(huì)報(bào)溢出錯(cuò)誤,值對(duì)于 Int32 太大或太小,而 (int) 不報(bào)錯(cuò),但是返回值為 -1。
如此可見(jiàn),我們?cè)谶M(jìn)行數(shù)據(jù)轉(zhuǎn)換前選擇轉(zhuǎn)換方法要謹(jǐn)慎,如果是數(shù)字類(lèi)型可以考慮直接用(int)強(qiáng)制轉(zhuǎn)換,如果是整型字符串類(lèi)型的,考慮用 int.Parse() 進(jìn)行轉(zhuǎn)換,如果不是這兩種類(lèi)型,再考慮用 Convert.ToInt32() 進(jìn)行轉(zhuǎn)換。
3.Convert.ToDouble 與 Double.Parse 的區(qū)別
實(shí)際上 Convert.ToDouble 與 Double.Parse 較為類(lèi)似,實(shí)際上 Convert.ToDouble內(nèi)部調(diào)用了 Double.Parse:
(1)對(duì)于參數(shù)為null的時(shí)候:
Convert.ToDouble參數(shù)為 null 時(shí),返回 0.0;
Double.Parse 參數(shù)為 null 時(shí),拋出異常。
(2)對(duì)于參數(shù)為""的時(shí)候:
Convert.ToDouble參數(shù)為 "" 時(shí),拋出異常;
Double.Parse 參數(shù)為 "" 時(shí),拋出異常。
(3)其它區(qū)別:
Convert.ToDouble可以轉(zhuǎn)換的類(lèi)型較多;
Double.Parse 只能轉(zhuǎn)換數(shù)字類(lèi)型的字符串。
Double.TryParse 與 Double.Parse 又較為類(lèi)似,但它不會(huì)產(chǎn)生異常,轉(zhuǎn)換成功返回 true,轉(zhuǎn)換失敗返回 false。最后一個(gè)參數(shù)為輸出值,如果轉(zhuǎn)換失敗,輸出值為 0.0。
關(guān)于類(lèi)型轉(zhuǎn)換的分享就到這里,想要學(xué)習(xí)更多課程請(qǐng)點(diǎn)擊:
https://bycwedu.vipwan.cn/promotion_channels/630597732