日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

Effective C#(二)

發布時間:2024/4/17 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective C#(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我勒個去……過了整整仨月,才看完一章,我是有多懶了。。。。不過最近工作忙,而且新房還裝修。一體檢還查出個過度疲勞。似乎賣苦肉計也沒啥意思哈。。。。以后盡量勤奮點吧!嗯啊~ Chapter 2 .NET Resource Management ? ? ?GC通過定義“代”的概念來優化回收工作。可以篩選出更加有“潛質”的回收對象。所有自上次GC以后創建的對象是第0代。經過一次GC后仍存在的,升級為第1代。再經過一次GC后仍存在的升級為第2代(最高)。每一次GC都會檢查第0代的對象,大約10次GC才會檢測一次第1代的,而大約100次GC才會檢測一次第2代的對象。這樣設計,是為了將局部變量快速地遍歷回收,同時保證一些全局的一直被使用的對象不每次都被遍歷。 ? ? ?在C#中,使用Finalizer來釋放資源并不是一個好主意。因為Finalizer只有在對象被GC時才被調用。所以被調用的時機是未知的。 ? ? ?存在Finalizer的對象,必須要等到下一個GC周期才能被析構。因為Finalizer不能在GC的線程中被調用。GC會將存在Finalizer的對象存入一個隊列,再開一個線程給他們。所以Finalizer會使本可以被迅速回收的局部變量的代數迅速升級。
  • Prefer Member Initializer To ?Assignment Statements
    • 隨著類的構造函數的增多,可能會造成一些成員變量沒有被同步地初始化的情況。避免這種情況的一個解決辦法就是在聲明它們時就初始化。編譯器會將聲明時初始化編譯為所有構造函數方法體之前的一段初始化代碼,而且是按照你定義的順序。這樣保證構造函數中所有聲明初始化已經完成。
    • 但是,當你需要給變量初始化為0或者null時,不要使用聲明初始化。如果不使用,系統會在較低的level為這片內存區域設置為0或者null。這是非常高效的。反之,編譯器需要在代碼中加入額外的賦值指令。這樣做不錯,只是效率不如前者高。
    • 當你需要在構造函數中根據參數初始化一些成員變量時,不要使用聲明初始化。因為這樣聲明初始化的對象生成后直接就被GC掉。
    • 當你需要捕捉初始化的異常時,不要使用聲明初始化。因為它無法放在try...catch中。
  • Use Proper Initialization For Static Class Member
    • 靜態構造函數在對應的類型第一次訪問之前被調用。所以可以用來進行需要一些邏輯的靜態初始化。例如:異常捕獲。
  • Utilize using and try/finalize for Resource Cleanup
    • 所有含有非托管資源的類型都實現的IDisposable接口。應當顯示調用他們的Dispose()方法來釋放內存。
    • 當對象拋出異常時,Dispose()可能沒有被調用。最簡單的解決方法是使用using將非托管對象包圍起來。using會在編譯時生成try/finalize語句塊。
    • using(){}中的對象類型必須是實現了IDisposable接口的。如果不是,可以用as騙過編譯器。但效果相當于using(null){},不會有任何意義。
    • 當有多個非托管對象同時出現時,可以自己手寫try/finalize語句塊。嵌套using()也成,只是結構會比較難看。。。
    • 也可以用Close()來釋放非托管資源。但與Dispose()不同的時,Close()在釋放資源后不會將它從GC的Finalize Queue中移除。所以Dispose()比Close()更好。
    • Dispose()不會將對象從內存移除,只是讓對象釋放非托管資源,例如數據庫連接。這時,這塊內存還在,但是數據庫連接已經斷開了。
  • Avoid Creating Unnecessary Objects
    • 作者最想說的就是不要在方法里面創建引用類型的對象,尤其是頻繁調用的方法。如何避免呢,有下面三個方法。
    • 把一直重復使用的對象提升為全局對象,避免每次都創建。
    • 一些常量的對象寫成靜態屬性。只在獲取時創建。
    • 對于一些不可變的對象,實現一個可以構造器。例如string和StringBuilder。
  • Implement the Standard Dispose Pattern
    • 實現你自己的Dispose模式時,一定要寫Finalizer,雖然會有一些性能損耗,但可以保證非托管資源一定能被釋放。
    • 實現Dispose模式需要做4件事:
      • 釋放非托管資源
      • 釋放托管資源
      • 設置一個標志位,標明這個對象已經被Dispose。其它方法被調用時,拋出ObjectDisposedException。
      • 觸發Finalization。
    • 只在需要的時候寫Finalization,否則會造成性能開銷。
    • 永遠不要在Finalizer和Dispose中做釋放資源以外的事情。
    • 可以寫一個Helper method:void Dispose(bool isDisposing)。
public class MyResourceHog : IDisposable { private bool alreadyDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing) { if (alreadyDisposed) return; if (isDisposing) { // elided: free managed resources here. } // elided: free unmanaged resources here. alreadyDisposed = true; } public void ExampleMethod() { if (alreadyDisposed) throw new ObjectDisposedException( "MyResourceHog", "Called Example Method on Disposed object"); // remainder elided. } } ? ??
  • Distinguish between Value Types and Reference Types
    • 值類型一般用于存儲數據,而引用類型一般用于包含行為、實現繼承和多態。
    • 決定一個自定義的類型是值類型還是引用類型很重要。將一個引用類型改為值類型會帶來深遠的影響。值類型將不再支持繼承和多態,而且作為參數或返回值傳遞時,會產生一個新的對象。
    • 如果拿不定主意,選擇引用類型。
  • Ensure 0 is a Valid State for Value Types
    • 所有的值類型都會在初始化時將內部的值置為0,這是C#語言的特性,你無法改變,你只能去適應。
    • 對于enum,最好將0作為一個合理的值。否則EnumType aaa = new EnumType();這樣的語句會造成一個無效的enum值。如果是作為位操作使用,請將0作為None使用,即每一種情況都沒有選中。
  • Prefer Immutable Atomic Value Types
    • 不可變的數據類型更易于維護。然而創建不可變數據并不容易。防止struct中的字段被濫改,可以使用屬性加以控制。但是過多的屬性也帶來過多的隱患。可以將屬性的set設為private。只在構造函數中進行賦值。如果更嚴格一點,可以將字段設為readonly,并且去掉屬性的set。
    • 對于struct中的引用類型要加倍小心。它們可能從外部被改變。保險的解決方案是在構造函數中進行復制,或者在屬性的get時進行復制。
    • 其它的防止struct中的字段被改變的方式兩個。一個是使用工廠方法。還有就是將多部操作進行封裝來構造不可變數據,例如StringBuilder和string。

轉載于:https://www.cnblogs.com/sigmadruid/p/5054330.html

總結

以上是生活随笔為你收集整理的Effective C#(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。