使用as和強制類型轉換的時候的區別是否僅僅是代碼形式上的區別。編程
答案是確定不是的。性能
看兩段代碼:code
object o = Factory.GetObject(); Student student = o as Student; if (student != null) { //dosomething }
和對象
object o = Factory.GetObject(); Student student = o as Student; try { Student student = (Student)o; if (student != null) { //dosomething } } catch (InvalidCastException e) { var str = e.Message; }
問題來了,這二者有什麼區別?blog
首先第二個裏面有一個損失性能的地方,就是try{}catch{}。ci
那麼能夠確定一點就是在程序健壯性相同的狀況下,使用as最好。get
問題又出現了,那麼何時不能用as呢?或者as 和 強制類型轉換之間差異是什麼呢?it
as 轉換的侷限性在於,他只會作簡單的裝箱和拆箱工做,而不會去作一些類型轉換。io
也就是說,若是待轉換的對象既不屬於目標對象,也不屬於派生出來的類型那麼是不能轉換的。編譯
這裏就有人奇怪了,若是二者都不屬於那麼轉換失敗正常啊。
怎麼說呢,請考慮下面兩種狀況:
1.數值之間轉換,好比int轉long之類的。
2.本身實現轉換,如:implicit
這二者as搞不定的。
好比說:
有一個child 類,想轉學生類。
這樣寫:
public class Child { public static implicit operator Student(Child child) { return new Student(); } }
而後我來這樣寫:
object o = Factory.GetObject(); Student student = o as Student; if (student != null) { //dosomething }
GetObject爲:
public static implicit operator Student(Child child) { return new Student(); }
這樣寫是不成功的。
圖我貼出來了。
那麼我這樣寫,是否能成功呢?
object o = Factory.GetObject(); try { Student student = (Student)o; if (student != null) { //dosomething } } catch (InvalidCastException e) { var str = e.Message; }
遺憾的是,這樣寫也是失敗的。
那麼爲何失敗呢?
C# 有一個編譯期和一個運行期。
而強制轉換髮送在編譯期。
也就是說它讀取的是object能不能轉換爲Student,而不是在運行期的Child。
好的,那麼你能夠這樣。
object o = Factory.GetObject(); var c = o as Child; try { Student student = (Student)c; if (student != null) { //dosomething } } catch (InvalidCastException e) { var str = e.Message; }
這樣是對的,可是對於編程學來講,誰會去這樣寫呢,在不少時候咱們應該儘可能避免裝箱和拆箱。
在此總結一下,那就是as 運行在運行期,而cast 在編譯期。
好的,as 完了後,看下is吧。
is 是遵照多態的,多態很好理解哈。
因此is 不是==的意思,而是是不是本身或者子類的意思。
若是你想要去獲得具體的類型判斷,那麼請使用getType更爲合適。
使用as或者 強制類型轉換沒有定性的要求,看具體的方案,而後呢當可使用as的時候儘可能使用as,畢竟能夠避免try catch這種消耗性能的東西。