• <td id="ae6ms"><li id="ae6ms"></li></td>
  • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
  • <table id="ae6ms"></table>
  • <td id="ae6ms"></td>
    <td id="ae6ms"></td>
  • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
  • <td id="ae6ms"></td>
  • <table id="ae6ms"><li id="ae6ms"></li></table>
  • <table id="ae6ms"></table>
    西西軟件園多重安全檢測下載網站、值得信賴的軟件下載站!
    軟件
    軟件
    文章
    搜索

    首頁編程開發C#.NET → C#會重蹈覆轍嗎?華而不實的C#析構器

    C#會重蹈覆轍嗎?華而不實的C#析構器

    相關軟件相關文章發表評論 來源:本站整理時間:2010/8/31 15:30:52字體大?。?em class="fontsize">A-A+

    作者:佚名點擊:62次評論:0次標簽: C# 析構器 C++

    API精靈FOR c#v2.35 最新版
    • 類型:編程輔助大?。?i>324KB語言:中文 評分:7.5
    • 標簽:
    立即下載

    前段時間去鳥國出差,顛倒黑白,碌碌無為,疏于寫博,請大家理解。下面繼續前貼7月《C與C++社區混戰,C#會重蹈覆轍嗎?》的討論。這次要談的是C#的析構器的問題。這是C#中非常華而不實的一個設計,不必要,且常常誤導很多C#er,且是.NET性能問題的常見陷阱地帶。下面逐項討論:

    1.C#析構器是一個丑陋的語法糖

    C#析構器(即Destructor)本質上是對Finalize方法的一個override。既然是對Finalize方法的override,那就大大方方讓程序員去override 根類Object的Finalize方法好了??墒?,C#設計師們首先搞了一個析構器,接著又在編譯器里面把父類的Finalize方法隱藏掉(你去override的時候,告訴你父類沒有Finalize方法)。但是編譯完后,在IL代碼中又告訴你override了父類中的Finalize方法,而你寫的析構器卻不翼而飛!

    我在編程語言歷史上看到很多語法糖,有些語法糖華麗,有些語法糖冗贅。但是還從沒見過如此彎彎繞的語法糖!

    2. C#析構器偏離了析構器原有的意思

    析構器自在各編程語言中造始,便有以下兩大基本含義:

    (a) 回收對象內部開銷的動態內存以及各種資源

    (b) 回收具有確定性時刻,比如delete對象時,或者棧cleanup時。

    可是C#將Finalize強扭成析構器后,徹底丟失掉前面兩大基本含義,既無法回收動態內存,又無法確定時刻調用(只能等GC在猴年馬月想起來才調用)。而只用于回收資源(而即便連這個任務也完成得很差,參見3.C#析構器不能完成其設計的初衷)。這使得很多沿用以前析構器概念的程序員經常犯如下錯誤,比如:

    class MyClass {

    object field;

       ~MyClass() { field=null; } //既不必要,也嚴重損傷性能

    }

     

    class MyClass {

    object field;

       ~MyClass() { GC.Collect(); } //既不必要,也嚴重、嚴重損傷性能

    }

    3. C#析構器不能完成其設計的初衷

    前面說過C#析構器主要用于釋放對象的資源(非托管資源),而非內存。

    但很不幸,對于C#析構器這個唯一的任務,它卻不能很好地勝任。因為C#析構器(也就是Finalize方法)是由GC調用的,而GC只會在猴年馬月想起來才調用(回收對象之前的一輪回收),往往延誤了對象資源的釋放——而對象資源是非常昂貴的?!∪绻娴倪@樣來做的話,項目會倒大霉——比如我們以前的一個項目,有部分程序員在析構器中釋放一些native內存,最后導致內存暴漲——用戶抱怨下來,最后一調試發現原來都是在析構器惹得禍——這些析構器半天沒有被GC調用!

    實際上,C#設計者在后來意識到這個問題了,于是又推出來一個Dispose方法(即Dispose模式)來讓用戶顯式釋放資源。然后又推薦程序員在Dispose里面GC.SuppressFinalize(). 即屏蔽析構器?!?/p>

    既然Dispose能將事情(確定性地釋放非托管資源)做好,析構器如此沒用,當初設計它干嗎?這是再典型不過的多余設計了!

    4. C#析構器會帶來嚴重的性能障礙

    a) C#析構器會將對象的代標記(Generation)拖大,使得對象更難以被GC回收,給GC造成更大性能負擔。

    b) 析構器本身釋放資源較晚,造成資源緊張,影響系統性能。

    c) 析構器執行需要一個單獨的線程開銷,該線程的執行(必須時間很短)需要其他線程停止,也是一個性能負擔。

    這也是為什么C#推薦實現Dispose,不推薦實現析構器的原因。因為析構器的性能代價太大??赡苤行№椖康拈_發人員感受不到這一點,但我相信做過大型項目的朋友,對C#析構器的性能問題會有非常深的體會。

    綜上,C#析構器是C#設計師們純粹為了炫耀自己華麗語法糖、而不小心又失了手藝、一個拙劣的設計。

    [ Update: ] 聽從網友的建議,把文章中“腦抽型、臭腳、sucks”等“罵街”的話刪除掉了。寫這些“罵街”的話實在是昨晚文章寫到深處,肝火旺盛,想到某些言論,情不自禁而已。并非我就是“潑婦”,今天一看自己昨晚的言論確實火力太猛,接受大家的意見,改正語言風格,希望下面堅持“技術討論不罵街“的原則。如果我有時候情不自禁做不到,希望大家監督指點,我會及時改過自新,重新做人:)

      相關評論

      閱讀本文后您有什么感想? 已有人給出評價!

      • 8 喜歡喜歡
      • 3 頂
      • 1 難過難過
      • 5 囧
      • 3 圍觀圍觀
      • 2 無聊無聊

      熱門評論

      最新評論

      發表評論 查看所有評論(0)

      昵稱:
      表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
      字數: 0/500 (您的評論需要經過審核才能顯示)
      女人让男人桶30分钟免费视频,女人张开腿让男人桶个爽,一进一出又大又粗爽视频
    • <td id="ae6ms"><li id="ae6ms"></li></td>
    • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
    • <table id="ae6ms"></table>
    • <td id="ae6ms"></td>
      <td id="ae6ms"></td>
    • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
    • <td id="ae6ms"></td>
    • <table id="ae6ms"><li id="ae6ms"></li></table>
    • <table id="ae6ms"></table>