今天在看一篇有關數據類型的文章的時候,無意間看到了兩個關鍵詞,“隱式轉換”與“顯示轉換”,然后突然想起了當初開始學編程的時候,也總是在代碼編譯的時候遇到這樣的問題。
那么,今天剛好有空來總結一下這兩者之間到底存在着怎么樣的關系。
先來看看如下幾個問題:
我先定義了一個變量:
string a = 5;
這個只要是有點常識的人都可以一眼看出問題所在。
然后在看看如下代碼:
double d1 = 5; float f1 = d1;
按我們所預料的那樣,現在我們試着嘗試編譯一下,然后通過控制台輸出f1。
結果盡然編譯的時候都無法通過,報出如下異常:
然后再看看如下代碼:
float f1 = 5; double d1 = f1; Console.WriteLine(f1);
再編譯,並運行。結果是編譯成功,並完美運行:
面對第一個編譯時出現的轉換,我們稍作修改,修改如下:
double d1 = 5; float f1 = (float)d1;
然后編譯,運行,結果是完美運行:
看到如此場景,有人會覺得好奇怪。
這里就關系到了我們之前所說的隱式轉換與顯示轉換。
隱式轉化:即數據的類型的轉換由編譯器自動進行的,不需要人工干預的數據轉換。
顯示轉換:與隱式轉換相反的數據類型的轉換,即需要人為強制干預的數據轉換。
而上述三段代碼編譯和運行,第一、第二段代碼的轉換就屬於隱式轉換,而第三段代碼則是使用了顯示轉換后才正確的執行。
那什么情況下兩個數據數據類型之間只需要隱式轉換就可以實現轉換,而什么情況下卻有需要進行強制轉換。
下面先來看一張表:
看完這張表,我們會發現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;
在編譯,結果顯示異常:
因此,在引用類型中,比如類與類之間的轉換,同樣都需要遵循隱式轉換與顯示轉換的原理和規則。
當然,有轉換就必有數據損失,這是無法避免的,只能說開發人員在使用這些數據類型轉換的時候要能夠明白可能會造成什么樣的損失,以及以怎樣最合理的方式使用它們,才能在使用過程中造成不必要的損失。