對C#而言,在做型別轉換時,撇開一些型別有提供Parse可供轉型外,通常我們有兩種選擇:一種是利用as運算子、一種則是強制轉型。作型別轉換時,應盡量採用as運算子來做轉型的動作,因為它比強制轉型安全,也具有較好的效能。

這邊讓我們直接來看個例子。假設今天我們寫一段程式,需將Object轉型為MyType。我們可以使用as運算子處理:

object o = Factory.GetObject();
        MyType t = o as MyType;
        if(t != null)
        {
            //轉型成功
        }else{
            //轉型失敗
        }

也可以使用強制轉型來做:

try
        {
            object o = Factory.GetObject();
            MyType t = (MyType)o;
            if (t != null)
            {
                //轉型成功
            }
            else
            {
                //Null
            }
        }
        catch
        {
            //轉型失敗
        }

很明顯的,使用as運算子來做轉型,程式會較為簡單易讀,不需添加例外處理,在效能上自然也不會有額外的負擔。強制轉型在使用上除了需作例外處理,也需外加null的判斷(主要是因為null可轉為任意型態)。而as運算子轉型就只需要檢查轉型後是否為null即可。

as運算子只能用於參考類型,不能應用於值類型(除非是Nullable的值類型)。像下面的程式就無法通過編譯器的編譯:

object o = Factory.GetObject();
        int i = o as int;

這是因為值類型不可為null導致(因若o無法轉型為整數,值類型也不可為null,其值無從填入i)。像這樣的值類型轉換,我們就可以使用強制轉型來處理:

object o = Factory.GetObject();
        int i = 0;
        try
        {
            i = (int)o;
        }catch { 
            //轉型失敗
        }

好一點的寫法,可以搭配is運算子來避免異常的發生

object o = Factory.GetObject();
        int i = 0;
        if (o is int)
            i = (int)o;

一般來說只有當不能使用as運算子作轉型動作時,才會考慮使用is運算子,不然多半會產生冗餘的程式碼。像是:

object o = Factory.GetObject();
        MyType t = null;
        if (o is MyType)
            t = o as MyType;

由上述,我們可以得知,在型別轉換的抉擇上,最好遵循著一個順序:

值得一提的是,我們常用的foreach語法,由於要同時支援值類型與參考類型,內部的轉型是採用強制轉型,若轉型失敗會產生InvalidCastException例外。