1. 程式人生 > >c# 優化程式碼的一些規則——使用is或as和強制型別轉換的區別[三]

c# 優化程式碼的一些規則——使用is或as和強制型別轉換的區別[三]

### 前言 使用as和強制型別轉換的時候的區別是否僅僅是程式碼形式上的區別。 答案是肯定不是的。 ### 正文 看兩段程式碼: ``` csharp object o = Factory.GetObject(); Student student = o as Student; if (student != null) { //dosomething } ``` 和 ``` csharp 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; } ``` 問題來了,這兩者有什麼區別? 首先第二個裡面有一個損失效能的地方,就是try{}catch{}。 那麼可以肯定一點就是在程式健壯性相同的情況下,使用as最好。 問題又出現了,那麼什麼時候不能用as呢?或者as 和 強制型別轉換之間差別是什麼呢? as 轉換的侷限性在於,他只會做簡單的裝箱和拆箱工作,而不會去做一些型別轉換。 也就是說,如果待轉換的物件既不屬於目標物件,也不屬於派生出來的型別那麼是不能轉換的。 這裡就有人奇怪了,如果兩者都不屬於那麼轉換失敗正常啊。 怎麼說呢,請考慮下面兩種情況: 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(); } ``` 這樣寫是不成功的。 ![](https://img2020.cnblogs.com/blog/1289794/202005/1289794-20200527172914342-308716460.png) 圖我貼出來了。 那麼我這樣寫,是否能成功呢? ``` 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這種消耗效能的