今天在看一篇有關數據類型的文章的時候,無心間看到了兩個關鍵詞,「隱式轉換」與「顯示轉換」,而後忽然想起了當初開始學編程的時候,也老是在代碼編譯的時候遇到這樣的問題。程序員
那麼,今天恰好有空來總結一下這二者之間到底存在着怎麼樣的關係。編程
先來看看以下幾個問題:spa
我先定義了一個變量:code
string a = 5;
這個只要是有點常識的人均可以一眼看出問題所在。blog
而後在看看以下代碼:開發
double d1 = 5; float f1 = d1;
按咱們所預料的那樣,如今咱們試着嘗試編譯一下,而後經過控制檯輸出f1。get
結果盡然編譯的時候都沒法經過,報出以下異常:編譯器
而後再看看以下代碼:string
float f1 = 5; double d1 = f1; Console.WriteLine(f1);
再編譯,並運行。結果是編譯成功,並完美運行:pm2
面對第一個編譯時出現的轉換,咱們稍做修改,修改以下:
double d1 = 5; float f1 = (float)d1;
而後編譯,運行,結果是完美運行:
看到如此場景,有人會以爲好奇怪。
這裏就關係到了咱們以前所說的隱式轉換與顯示轉換。
隱式轉化:即數據的類型的轉換由編譯器自動進行的,不須要人工干預的數據轉換。
顯示轉換:與隱式轉換相反的數據類型的轉換,即須要人爲強制干預的數據轉換。
而上述三段代碼編譯和運行,第1、第二段代碼的轉換就屬於隱式轉換,而第三段代碼則是使用了顯示轉換後才正確的執行。
那什麼狀況下兩個數據數據類型之間只須要隱式轉換就能夠實現轉換,而什麼狀況下卻有須要進行強制轉換。
下面先來看一張表:
看完這張表,咱們會發現float類型表示的是32位的浮點值,而double類型表示的是64位的浮點值。恰好float轉換成double則隱式轉換就可實現,而double轉換到float則須要強制轉換,就是顯示轉換。
而double類型的值範圍大於float類型的值範圍,因此float轉double能夠隱式轉換,double轉float卻須要顯示轉換。
由此得出以下結論:
當被轉換類型的值範圍小於目標類型的值範圍時能夠執行隱式轉換,不然隱式轉換是編譯器會報異常。也就是說大存儲容量的數據類型能夠容納小存儲容量的數據類型,反之則不行。
那麼隱式轉換要具有的條件是:
1. 被轉換類型的值範圍必須包含目標類型的值範圍;
2. 被轉換類型的值必須與目標類型兼容。
而顯示轉換要被的條件則是:
1. 被轉換類型的值要在目標類型的值範圍之類,若是超出目標類型的最大或最小值,則編譯器會拋出異常,轉換不成功。
2. 被轉換類型的值一樣必須與目標類型互相兼容。
一樣,隱式轉換與顯示轉換在引用類型中一樣適用。下面定義了兩個類。
/// <summary> /// 人類 /// </summary> public class Persion { public int Id { get; set; } public int Sex { get; set; } public int Age { get; set; } public int Height { get; set; } } /// <summary> /// 程序類 /// </summary> public class Programmer : Persion { public string Job { get; set; } public string Postion { get; set; } }
以上兩個類的字段隨意定義,可能不合理,在此只是說明其轉換的問題。
而後作以下初始化和轉換:
Programmer pm1 = new Programmer() { Id = 1, Age = 25, Height = 168, Job = "程序員", Sex = 1 }; Persion p1 = pm1;
編譯之後,顯示編譯經過:
再看另外一段代碼:
Persion p2 = new Persion() { Id = 1, Age = 20, Sex = 1, Height = 180 }; Programmer pm2 = p2;
在編譯,結果顯示異常:
所以,在引用類型中,好比類與類之間的轉換,一樣都須要遵循隱式轉換與顯示轉換的原理和規則。
固然,有轉換就必有數據損失,這是沒法避免的,只能說開發人員在使用這些數據類型轉換的時候要可以明白可能會形成什麼樣的損失,以及以怎樣最合理的方式使用它們,才能在使用過程當中形成沒必要要的損失。