iT邦幫忙

DAY 3
2

.NET程式效能Issue系列 第 3

[Day 3][C#]Effective C# 條款三: 運算子is或as優於強制轉型

  • 分享至 

  • xImage
  •  

對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運算子只能用於參考類型,不能應用於值類型。像下面的程式就無法通過編譯器的編譯:

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例外。


上一篇
[Day 2][C#]Effective C# 條款二: 運行時常數優於編譯時常數
下一篇
[Day 4][C#]Effective C# 條款四: 使用ConditionalAttribute替代#if條件編譯
系列文
.NET程式效能Issue11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言