標籤:註冊 應用 修改 註冊表 tar 編譯 特定 工作量 com
《Effective C#》快速筆記 - C# 高效編程要點補充
目錄
- 四十五、盡量減少裝箱拆箱
- 四十六、為應用程式建立專門的異常類
- 四十七、使用強異常安全保證
- 四十八、盡量使用安全的代碼
- 四十九、實現與 CLS 相容的程式集
- 五十、實現小尺寸、高內聚的程式集
這是這一系列的最後一篇。
四十五、盡量減少裝箱拆箱
- 實值型別是資料的容器,不支援多態。
- 裝箱把一個實值型別放在一個未確定類型的引用對象中,讓該值作為參考型別所使用。拆箱指從參考型別的位置取出值的一個副本。
- 裝箱拆箱都是比較影響效能的手段,應該儘可能的避免裝拆箱操作。
- 泛型可以避免裝拆箱操作。
- 實值型別裝箱是隱式的,難以發現,需要自己多加註意。
四十六、為應用程式建立專門的異常類
1.只有你覺得使用者會使用不同的形式去處理錯誤時,才應該建立不同的異常類。
2.自訂的異常類應該以“Exception”結尾,並且繼承 System.Exception 或其他異常類。不過你也需要適當地包含該基類中的建構函式,內容直接交給基類實現即可。
/// <summary> /// 自訂的異常類 /// </summary> public class MyException : Exception { public MyException() : base() { } public MyException(string s) : base(s) { } public MyException(string s, Exception e) : base(s, e) { } protected MyException(SerializationInfo info, StreamingContext cxt) : base(info, cxt) { } }
3.在拋出你自訂的異常時,應該將原始的異常存放在 InnerException 屬性中,這樣就可以顯示足夠友好,並且資訊豐富的異常:
public void Do() { try { //DoException(); } catch (DoException e) { var msg = $"該問題是博主故意引起的"; throw new MyException(msg, e); } }
4.只有在存在不同類型的恢複操作時,才應該拋出不同類型的異常,定義異常類時,還要提供基類中支援的所有建構函式。此外,不要忘記使用 InnerException 屬性來儲存低層次的異常資訊。
四十七、使用強異常安全保證
1.Dave Abrahams 定義了 3 種安全異常來保證程式:基礎保證、強保證,以及無拋出保證。
2.強異常保證:如果一個操作因為某個異常中斷,程式將維持原狀態不變,操作要麼徹底完成,要麼就不會修改程式的任何狀態。強異常保證的好處:任何時候若是捕獲了異常,所有將要嘗試的正常操作都不繼續進行,也就是不會繼續進行修改。程式當前的狀態如尚未開始進行該操作一樣。
四十八、盡量使用安全的代碼
- .NET 運行時可以保證一些懷有而已的代碼不能直接滲透到遠端電腦上執行。
- CLR 中的一些代碼訪問安全設定,如:CLR 強制要求基於角色的安全認證,這樣才能判斷某些代碼能否在基於一個特定的角色帳號下運行。
- CLR 可以檢查 IL 代碼,確保它不存在潛在的危險行為。如:直接存取原始記憶體。
- 如果代碼不需要任何的安全許可權,就不需要使用 CAS 的 API 來判斷存取權限,因為這樣只會影響效能,額外增加 CLR 的工作量。
- 你可以使用 CAS 的 API 來訪問一些受保護的資源,一般需要額外的許可權。如非託管的記憶體和檔案系統、註冊表等。
- 一般來說,我們編寫的 C# 代碼都是安全的,除非你使用了 /unsafe。
- 應該儘可能地避免訪問非託管記憶體。確實有需要的話,應該將其隔離在獨立的程式集中。
四十九、實現與 CLS 相容的程式集
1..NET 運行環境與語言無關,我們建立的程式集必須與 CLS 保持相容,這樣才能保證其他的開發人員可以用另一種語言來調用你的組件。
五十、實現小尺寸、高內聚的程式集
- 如果我們都將所有的代碼放在一個程式集中,這不利於組件的重用,也不利於系統的局部更新,若是可以將其拆分成小程式集,以組件的形式進行重用,就可以從一定程度上簡化後續的開發工作。
- 我們用類進行功能的封裝和資料的儲存,只有公有的類、結構和介面才應該稱為契約,被其它使用者(或程式集)進行訪問。
- 建議將程式拆分成多個程式集,把相關的類型放在同一個程式集中。
- 一個程式集應該是一個包含相關功能的,具有良好組織的一個庫。如果不知道怎樣的顆粒度最好,可以略微向小而多的方向傾斜。
- 如果所有參數和傳回值都是介面,那麼任何一個程式集都可以很容易地用另一個實現了相同介面的程式集進行代替。
- 更小的程式集同樣可以降低程式啟動時的開銷。更大的程式集要花上更多的 CPU 時間來載入,且需要更多的時間來將必須的 IL 編譯成機器指令。雖然只有啟動時將被調用的代碼會被 JIT 編譯,但程式集是整體載入的。
- 在跨越程式集時,安全性檢查會成為一個額外的開銷。程式跨越程式集的次數越小,其執行效率越高。
- 效能的損耗對我們來說可以忽略不計,因為在開發時,我們著重的是代碼的靈活度,所以不要擔心將大程式集拆分成小程式集的效能問題。
- 常見的程式集:小且僅專註於某個特定功能的程式集,大一些但包含通用功能的程式集,無論何種情況,都應該保證其儘可能合理的小,但不應該過度。
本系列
《Effective C#》快速筆記(一)- C# 語言習慣
《Effective C#》快速筆記(二)- .NET 資源託管
《Effective C#》快速筆記(三)- 使用 C# 表達設計
《Effective C#》快速筆記(四) - 使用架構
《Effective C#》快速筆記(五) - C# 中的動態編程
[.NET] 《Effective C#》快速筆記 - C# 高效編程要點補充