1. 程式人生 > >C#中的型別轉換大總結

C#中的型別轉換大總結

使用C#一個最常見的問題便是各種型別間的轉換。我們知道,C#中的型別分為值型別和引用型別兩大類。但是,有關它們間各自轉換的細節描述在網上很少得到詳細的回答。現在,我結合搜尋到的部分資料整理如下:

1,問題

c#中型別轉換的有兩種,()轉換和convert轉換。

我想知道的是這兩個轉換的區別

還有就是()轉換我用了發現好多不能轉換過來,但是convert是萬能轉換的,

那什麼時候該用()什麼時候該用convert呢?

最後問下子,把int sum怎麼用()轉換成float型別?

請詳細說明,最好有舉例。

解答:

(1)這兩個方法的最大不同是它們對null值的處理方法:
Convert.ToInt32(null)

會返回0而不會產生任何異常,但int.Parse(null)則會產生異常。

沒搞清楚Convert.ToInt32int.Parse()的細細微區別時千萬別亂用,否則可能會產生無法預料的結果,

舉例來說:假如從url中取一 個引數page的值,我們知道這個值是一個int

所以即可以用 Convert.ToInt32(Request.QueryString["page"])

也可以 用,int.Parse(Request.QueryString["page"]),但是如果page這個引數在url中不存在,

那麼前者將返回00可能是一個有效的值,所以你不知道url中原來根本就沒有這個引數而繼續進行下一下

的處理,這就可能產生意想不到的效果,而用後一種辦法的話沒有page這個引數會丟擲異常,

我們可以捕獲異常然後再做相應的處理,比如提示使用者缺少引數,而不是把引數值當做0來處理。

(2)還有一點區別就是
a. Convert.ToInt32(double value)
如果 value為兩個整數中間的數字,則返回二者中的偶數;即 3.5轉換為44.5轉換為 4

5.5 轉換為 6。 不過4.6可以轉換為54.4轉換為4
b. int.Parse("4.5")
直接報錯:"輸入字串的格式不正確".

c. (int)4.6 = 4
Int
轉化其他數值型別為Int時沒有四捨五入,
強制轉換

int.Parse

是轉換Stringint
Convert.ToInt32
是轉換繼承Object的物件為int
.
你得到一個object物件,你想把它轉換為int,int.Parse就不可以,要用
Convert.ToInt32.

個人總結:
(1)Convert.ToInt32
的引數比較多,Int.Parse只能轉換string型別的.
(2)Parse
就是把String轉換成int,char,double....,

也就是*.Parse(string)括號中的一定要是string.
(3)Convert
可以提供多種型別的轉換,也就是Convert.*()括號中可以為很多種型別(包括string).

2,問題:

如何使用 as is運算子安全地進行強制轉換?

解答:首先,在MSDNhttp://msdn.microsoft.com/zh-cn/library/cc488006.aspx)給出的解釋非常簡單,過於簡單。更詳細的解釋如下:

在程式中,進行型別轉換是常見的事。那麼在C#中支援以前語言的型別轉換方法,

即用型別名進行強行轉換,例如:

object objTest =new NewType();

NewType newValue = (NewType)objTest;

但是這樣轉換,有個嚴重的問題,就是在把objTest強轉換成NewType型別物件的時候,

這個過程是不安全的,因此需要用try-catch語句來進行保護。這樣一來,

比較安全的程式碼方式應該如下所示。

   object objTest =new NewType();

   NewType newValue =null;

   try

    {

        newValue = (NewType)objTest;

    }

   catch( Exception err )

    {

        MessageBox.Show( err.Message );

    }

但是如上的寫法在C#中已經屬於過時的寫法,而且也屬於比較低效的寫法。

C#中比較高效而且安全的寫法,應該用as操作符,那麼完成如上類似功能的正確程式碼應該如下。

   object objTest =new NewType();

    NewType newValue = objTest as NewType;

那麼很明顯,如上的寫法首先看起來很簡便,至少程式碼數量和強轉方式一樣。至於安全性,

對於as操作符來說,它不會做過的轉換操作,當需要轉換物件的型別屬於轉換目標類

型或者轉換目標型別的派生型別的時候,那麼此轉換操作才能成功,而且並不產生新

的物件。因此用as來進行型別轉換使安全的。為什麼用as操作符進行型別轉換的效率要高於

老式的型別轉換的,因為用as操作符進行轉換就如前面所說的,首先判斷當前物件的型別,

當型別滿足要求後才進行轉換。而傳統的型別轉換方式,是用當前物件直接去轉換,而且

為了保護轉換成功,要加上try-catch,這就決定了它的效率不會高於as操作符的效率。

要注意的時候,不管用傳統方式,還是用as操作符進行型別轉換之後,在使用之前,

需要進行判斷轉換是否成功,如下:

   if( newValue!=null)

    {

       //Work with the object named "newValue"

    }

但是,使用as操作符有如下幾點限制。

第一個就是,不用在型別之間進行型別轉化,即如下編寫就會出現編譯錯誤。

NewType newValue =new NewType();

NewType1 newValue = newValue as NewType1;

第二個就是,不能應用在值型別資料,即不能如下寫(也會出現編譯錯誤)。

   object objTest = 11;

   int nValue = objTest as int;

對於第一點所提的,可以用傳統的型別轉換方式來完成,但是光用如下的方式,是不能正確完成。

    NewTypeOne newTestOne =new NewTypeOne();

    NewTypeTwo newTestTwo = (NewTypeTwo)newTestOne;

但是光如上寫是不能完成的,要想使如上的操作能正確完成,在原有型別中增加型別轉換

操作符函式,即需要完成類似如下的程式碼。

   public class NewTypeOne

    {

       public static explicit operator NewTypeTwo( NewTypeOne objTest )

        {

           //Convert object into new type

        }

    }

對於第二點所提的,在C#中可以使用is操作符,再加上老式的型別轉換操作,就可以安全完成

轉換,那麼要完成如上操作,正確的寫法如下。

   object objTest = 11;

   if( objTest is int)

    {

       int nValue = (int)objTest;

    }

除了如上兩點限制外,在用as操作符來進行型別轉換的時候,有個細微的問題。在前面

所說的,用as來進行型別轉換的時候,所要轉換的物件型別必須是目標型別或者轉換目

標型別的派生型別,那麼這樣就有個問題,即用as操作符來進行型別轉換的時候無法轉

換成正確的型別,也就是說本來應該轉換成子型別,卻轉換成了父型別。但是我並不認

為這是個嚴重問題,因為在用as操作符來進行型別轉換的時候,如何選擇目標型別在編

碼的時候已經很明確了,即用父型別作為目標型別,那麼型別轉換的目的就是轉換成父

型別物件進行操作;反之亦然。

C#中已經提供了一個很好的型別轉換方式,那麼在進行型別轉換的時候,可以按照如

下的方式進行選擇。

型別轉換

使用選擇

Object =>已知引用型別

使用as操作符來完成

Object =>已知值型別

先使用is操作符來進行判斷,再用型別強轉方式進行轉換

已知引用型別之間轉換

首先需要相應型別提供轉換函式,再用型別強轉方式進行轉換

已知值型別之間轉換

最好使用系統提供的Convert類所涉及的靜態方法