口袋筆記系列著重於記錄日常的小技術點,點與點之間雖然可能聯系不大。但足夠小,也便於熟悉並運用到日常的開發周期中,產生實際的效益。記住是第一步,不是最終目的。最終目的是在了解原理下開發出兼顧靈活性、可擴展性、可移植性的高效益程序。本系列隨以C#的小知識點開篇,但後續不局限於某種特定語言。來源於手中日常摘錄的資料和書籍,算是對看過的東西的總結,部分注有閱讀心得,也有部分只提出大綱或結論。(備注:本篇文章中大部分要點需要有實際的開發經驗,有助於閱讀理解。)
當編譯期常量const被編譯成IL時,它就已經被替換成所代表的字面數值。所以更改一個公有的編譯期常量的值,需要重新編譯所有引用到該常量的代碼以保證所有代碼使用的是最新的常量值。
相反,運行時常量被編譯成IL時引用的是readonly的變量,而不是變量的值,只需要重新編譯更改了常量值的代碼,就能實現對其它已經發布的代碼在二進制層次上的兼容。分兩種情況:
轉換的目標類型是引用類型:使用is測試能否轉換成功,然後再用as進行轉換(as在轉換對象為null時會返回null)。as和is不會執行用戶自定義的轉換,只有當運行時類型是目標類型或者是目標的派生類型,才會轉換成功。執行用戶自定義的轉換可以用強制轉換。 轉換的目標類型是值類型:不能使用as,可以使用強制轉換。
GetHashCode覆寫規則
委托應用於回調
接受Predicate<>、Action<>、Func<>為參數的方法,如List<T>.Find(Predicate<T> p);有時傳入lambda表達式,編譯器會把lambda表達式轉換成方法,然後創建一個委托,指向該方法,然後調用委托實現回調。
委托應用於事件
.NET的事件模式就是觀察者模式
public event EventHandler<LoggerEventArgs> Log;
編譯器會自動創建類似下面的代碼,根據需要可以自己編寫
private EventHander<LoggerEventArgs> log;
public event EventHander<LoggerEventArgs> Log
{
add{log=log+value;}
remove{log=log-value;}
}
事件相當於一個委托集合,可以添加多個同類型委托(通過+=);
(2)終結器
終結器只是一種防御手段,僅僅能夠保證給定類型的對象所分配的非托管資源最終被釋放。GC會把需要執行終結的對象放在專門的隊列中,然後讓另一個線程來執行這些對象的終結器。這樣,GC可以繼續執行其當前的工作,在內存中移除垃圾對象,而在下一次的GC調用中才會從內存中移除這些已被終結的對象。可以看到,需要調用終結器的對象將在內存中多停留一個GC周期的時間(實際情況會比這個更復雜一點,詳情請查看下面“代”的概念),所以應該盡量少讓代碼的邏輯使用到終結器。
GC為了優化執行,引入了“代”(generation)的概念。可以快速地找到那些更有可能是垃圾的對象。自上一次垃圾收集以來,新創建的對象屬於第0代對象。若某個對象在經歷過一次垃圾收集之後仍舊存活,那麼將成為第1代對象。兩次及兩次以上垃圾收集後仍沒有被銷毀的對象就變成了第2代對象。這樣能將局部變量和應用程序生命周期一直使用的對象分開對待。第0代大多屬於局部變量。而成員變量和全局變量則會更快地成為第1代對象,直至第2代。GC將通過減少檢查第1代和第2代對象的次數來優化執行過程。在每個周期中,GC都會檢查第0代對象。一般來說,大概10個周期的GC中,會有一次去同時檢查第0代和第1代對象。大概100個周期的GC中,會有一次同時檢查所有對象。可以看到一個需要總結的對象可能會比普通對象多停留9個GC周期。而若是再次GC的時候仍沒有完成終結炒作,那麼該對象將繼續被提升為第2代。對於第2代的對象,往往需要100次以上的GC周期才會有機會被清除。為了避免這個性能問題,建議使用IDisposable接口。
(3)Dispose()和Close()
使用了非系統資源的類型會自動在終結器中調用Dispose(),以便在使用者忘記的時候仍保證能正常釋放資源,但這些資源會在內存中停留更長時間,所以最好的方案還是由使用者自己顯示地使用IDisposable接口的Dispose()來釋放。Dispose()並不是將對象從內存中移除,而只是讓對象釋放掉其中的非托管資源。
Dispose()和Close()的區別(Dispose()比Close()要好一些)
Close:清理資源,對象已經不需要被終結,但一般沒有調用GC.SuppressFinalize(),所以對象仍舊在終結隊列中。
Dispose:清理資源,調用GC.SuppressFinalize()告知GC該對象不再需要被終結
使用IDisposable.Dispose()實現銷毀非托管資源的標准銷毀模式
(4)using using語句能以最簡單的方式保證用戶的對象可以正常銷毀,即使對象在調用操作時出現異常。當有多個對象需要銷毀時,可以使用多個using塊或一個try/finally塊。 using(){}=try{}finally{xxx.Dispose();} 下面例子能保證當obj不為null時正確清理到對象,當obj為null時,using(null)也不會報錯,但不會做任何清理工作。 object obj=Factory.CreateInstance(); using(obj as IDisposable) { Console.Write(obj.ToString()); }
作者:B.it
出處:http://www.cnblogs.com/ImBit/p/5484920.html
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。