由於本章是屬於本書的最最最基礎部分,所以我們在講述知識的同時也很注重學習方法和Visual Studio等工具的使用說明。
顯示轉換就需要特殊類或者方法來輔助完成了。例如
long lo = 1; //申明一個long類型變數
byte b = Convert.ToByte(lo);//使用Convert類轉換
short sh = (short)lo; //使用強型別轉換
int i = int.Parse(lo.ToString());//使用類型中的Parse方法轉換
從上面的例子來看,我們應該很容易想到一個比較嚴重的問題。因為上面都是縮小轉換。那麼這就存在是否能夠成功縮小和縮小的過程中是否會丟失資料或者損失精度。下面我們再做一個執行個體。步驟如下:
1.在上面建立的項目"類型轉換和裝拆箱"中的Form1表單上再增加一個按鈕,並將按鈕上的文字修改為"顯示轉換執行個體",2-16;
2.在上面建立的項目"類型轉換和裝拆箱"中添加一個新的Windows表單。在方案總管中要添加新檔的項目名稱上點擊滑鼠右鍵,選擇添加新項-->添加Windows表單'將新表單命名為Xszh.cs。添加方式2-21
圖2-21
小天:老田,你的解決方案自資源管理員中怎麼有那麼多的項目呢???我就是每次都只有一個。
老田:這個簡單了,你可以在vs的檔案菜單中選擇添加'建立項目,這樣就會把新的項目添加到解決方案中了。這個就不配圖了,自己摸索下。
3.雙擊"顯示轉換執行個體"這個按鈕,增加如下代碼:
///<summary>
///雙擊"顯示轉換執行個體"按鈕產生的事件,我們只是添加事件中的兩行代碼
///這是最後一次為自動產生的事件做注釋了,以後還不明白就要罰唱征服了
///</summary>
///<param name="sender">觸發事件的源</param>
///<param name="e">攜帶的訊息</param>
privatevoid button2_Click(object sender, EventArgs e)
{
Xszh xs = newXszh();//前面建立的Xszh表單其實也是一個類,用的就是它
xs.Show(); //顯示前面建立的那個表單
}
4.F5運行,試試看點擊"顯示轉換執行個體"按鈕,看是否會彈出新表單。成功的話就關閉表單,並確保VS停止調試狀態了(有時候電腦反應太慢會出現,表單已經關閉,但VS仍然處於調試狀態,這樣可能會導致代碼唯讀,甚至VS報錯)。如何確保呢,在VS調試狀態的時候,VS預設會增加一個名為"調試"的工具條,2-22
圖2-22
5.在Xszh表單上點擊右鍵->屬性,修改Text屬性為"顯示轉換執行個體"。
小提示:由於本章是屬於本書的最最最基礎部分,所以我們在講述知識的同時也很注重學習方法和Visual Studio等工具的使用說明。有基礎的朋友可以快速跳過這些內容,沒有基礎的朋友請不要單純的接收知識、模仿我的做法和步驟,一定要多想想,老田為什麼這樣來示範執行個體。其實我的這些過程、執行個體都是結合我自己的自學心得和在教學過程中很多同學容易犯錯,容易忽略的地方的經驗。所以相信絕對值得你認真參考。
例如:向方案總管中添加新項目、向項目中添加新項,修改控制項屬性、雙擊控制項產生事件代碼等等。
類似修改屬性的提示以後章節中也不會再提了,自己多去摸索下每個用到的控制項的其它屬性,都嘗試下,前面講了,在VS屬性面板中對每個屬性項都有說明,自己配合說明去舉一反三的練習
6.想表單上分別拖出一些Label控制項用於顯示說明和接收轉換結果。放一個TextBox用於輸入要轉換的數字。一個按鈕,用於執行轉換。一個GroupBox(在工具箱的容器分類中)。最終布局效果2-23
圖2-23
7.雙擊"給我轉按鈕",在事件中輸入下面代碼:
int i = int.Parse(textBox1.Text); //因為textBox1.Text是string類型,所以必須轉換
//下面是將int類型分別轉換,並將轉換結果在轉換為string類型交給對應的Label,
//因為Label.Text的類型也是string,所以最終還要再轉換到string後才能交給Label的Text屬性
//下面之所以要將(byte)i全部括起來,是因為我們要把整個i轉換成byte類型後的結果ToString,
//如果不將(byte)i全部括起來,那麼編譯器會誤認為我們是要把i.ToString()強型別為byte
lbl_byte.Text = ((byte)i).ToString();
lbl_short.Text = ((short)i).ToString();
lbl_long.Text = ((long)i).ToString();
lbl_float.Text = ((float)i).ToString();
lbl_double.Text = Convert.ToDouble(i).ToString();
8.接著就是F5,運行程式,記得隨便輸入數字(是那種比較瘦的數字,不要輸字元或者符號,也不要輸入比較胖的那種數字,那個被認為是字元);
小天:我發現我被C#忽悠了。因為他的轉換結果有錯,2-24,long和double是正確的,其它都是錯誤的。這咋整啊?
圖2-24
嘿嘿,這就是別人說的強扭的瓜不甜。不過C#也提供了驗證的方法。使用關鍵詞checked,它可以檢查資料類型轉換是否安全,如果不安全,就會讓運行庫拋出一個溢出異常,如下:
lbl_byte.Text = checked((byte)i).ToString();
lbl_short.Text = checked((short)i).ToString();
lbl_long.Text = checked((long)i).ToString();
lbl_float.Text = checked((float)i).ToString();
lbl_double.Text = checked(Convert.ToDouble(i).ToString());
小天:我看double類型是可以帶小數的,可是我嘗試輸入小數的時候就出錯了。
老田:所有的顯式資料類型轉換都可能不安全,在應用程式中應包含這樣的代碼,處理可能失敗的資料類型轉換。後面異常處理章節將使用try和 catch語句引入結構化異常處理。
使用資料類型轉換可以把大多數資料從一種基本類型轉換為另一種基本類型。例如:給price加上0.5,再把結果轉換為int:
double price = 25.30;
int approximatePrice = (int)(price + 0.5); //值為25,而小數點後面的0.80丟失了
小天:為什麼會丟失呢?
老田:在這個轉換過程中,小數點後面的所有資料都會丟失。因此,如果要使用這個修改過的價格進行更多的計算,最好不要使用這種轉換;如果要輸出全部計算完或部分計算完的近似值,且不希望用小數點後面的資料去麻煩使用者,這種轉換是很好的。
顯式數值轉換用於通過顯式轉換運算式,將任何數字類型轉換為任何其它數字類型。對於它不存在隱式轉換。下表顯示了這些轉換。
從 到
sbyte byte、ushort、uint、ulong或char
byte Sbyte或者char
short sbyte、byte、ushort、uint、ulong或char
ushort sbyte、byte、short或char
int sbyte、byte、short、ushort、uint、ulong或char
uint sbyte、byte、short、ushort、int或char
long sbyte、byte、short、ushort、int、uint、ulong或char
ulong sbyte、byte、short、ushort、int、uint、long或char
char sbyte、byte或short
float sbyte、byte、short、ushort、int、uint、long、ulong、char或decimal
double sbyte、byte、short、ushort、int、uint、long、ulong、char、float或decimal
decimal sbyte、byte、short、ushort、int、uint、long、ulong、char、float或double
顯示轉換需要注意以下幾點:
顯式數值轉換可能導致精度損失或引發異常。
將decimal值轉換為整型時,該值將舍入為與零最接近的整數值。如果結果整數值超出目標類型的範圍,則會引發 OverflowException。
將double或float值轉換為整型時,值會被截斷。如果該結果整數值超出了目標值的範圍,其結果將取決於溢出檢查上下文。在 checked 上下文中,將引發OverflowException;而在 unchecked 上下文中,結果將是一個未指定的目標類型的值。
將double轉換為float時,double值將舍入為最接近的float值。如果double值因過小或過大而使目標類型無法容納它,則結果將為零或無窮大。
將float或double轉換為decimal時,源值將轉換為decimal表示形式,並舍入為第 28 個小數字之後最接近的數(如果需要)。根據源值的不同,可能產生以下結果:
如果源值因過小而無法表示為decimal,那麼結果將為零。
如果源值為 NaN(非數字值)、無窮大或因過大而無法表示為decimal,則會引發OverflowException。
將decimal轉換為float或double時,decimal值將舍入為最接近的double或float值。
要把一個可空類型轉換為非可空類型,或轉換為另一個可空類型,但可能會遺失資料,就必須使用顯式轉換。重要的是,在底層基本類型相同的元素之間進行轉換時,就一定要使用顯式轉換,例如int?轉換為int,或float?轉換為float。這是因為可空類型的值可以是null,非可空類型不能表示這個值。只要可以在兩個非可空類型之間進行顯式轉換,對應可空類型之間的顯式轉換就可以進行。但如果從可空類型轉換為非可空類型,且變數的值是null,就會拋出InvalidOperationException。例如:
int? aa = null; //讓變數aa的值為null
int b = (int)aa;// 會拋出異常,和MSSQL一樣,C#中也認為null是未知
使用顯式的資料類型轉換方式,並小心使用這種技術,就可以把簡單實值型別的任何執行個體轉換為另一種類型。但在進行顯式的類型轉換時有一些限制,例如實值型別,只能在數字、char類型和enum類型之間轉換。不能直接把Boolean資料類型轉換為其它類型,也不能把其它類型轉換為Boolean資料類型。
如果需要在數字和字串之間轉換,.NET類庫提供了一些方法。Object類有一個ToString()方法,該方法在所有的.NET預定義類型中都進行了重寫,返回對象的字串表示:
int i = 10;
string s = i.ToString();
如果需要分析一個字串,獲得一個數字或Boolean值,就可以使用所有預定義實值型別都支援的Parse方法:
string s = "100";
int i = int.Parse(s);
小天:看來這個轉換還得多玩玩才行,只是你這樣一說,我覺得還是有很多不清楚的地方。不過我覺得你上面教我的例題練習起來太痛苦了。每次運行程式後我都需要跳一個完全不用的表單。但是我又不想為每一個例題都建立一個項目。
老田:是的,多練習,多舉一反三。至於你說每次都要跳一個沒用的表單這個問題,其實非常好解決,只需要在項目中的Program.cs檔裡面修改啟動類即可,2-25
圖2-25
小天:這一下就清淨了。我打算做10來個執行個體。按照上面寫的那麼多預定義類型挨個來試。
老田:要是你挨個試了,注釋也做得很清楚了,可以留下來作為以後自己隨時備用的資料庫。
另外,再提供一個學習方法(從這個例題中你應該看出一個舉一反三的思路,而不單純是知識點描述),如下例:
int a = 123; //申明int類型變數a
short b = 321; //申明short類型變數b
var c = a + b; //讓兩個不同類型的變數相加
Console.WriteLine(c.GetType());//混合類型的變數相加的值是什麼類型呢?為什麼呢?
當然,如果你願意的話,也可以將你的練習成果傳到本書最後指定的學習網站,和大家一起交流心得。
小提示:初學階段,做注釋其實就是進一步整理思路和加深印象的複習過程。因為你在做注釋的時候,你得整理你自己學習心得,你得再次看書來印證自己的理解。只有你能夠正確的把每一句代碼的注釋,每一段代碼的思路都寫出來了,這才能說明你真正的理解了這個知識點。
切忌練習就是照書抄代碼,抄完還不做注釋。如果你是這樣學習的話,我老田在這裡很認真的告訴你:"你早點去學其它的吧,編程這事你做不來的"。因為你這樣的做法根本學不會,你學不會其實也沒啥,最重要的是你還非說我的書沒有寫好。
本文為天轟穿原著,轉載請註明出處及作者!