c# - 在.NET中使用後將對象設置為Null / Nothing




7 Answers

Karl絕對正確,使用後不需要將對象設置為null。 如果一個對象實現了IDisposable ,只要確保在完成該對象(包裝在try ... finallyusing()塊)中時調用IDisposable.Dispose() )。 但即使您不記得調用Dispose() ,對象的終結器方法也應該為您調用Dispose()

我認為這是一個很好的待遇:

挖入IDisposable

和這個

了解IDisposable

試圖第二次猜測GC及其管理策略是沒有意義的,因為它是自我調整和不透明的。 關於在Dot Net Rocks上與Jeffrey Richter的內部工作進行了很好的討論: Windows存儲器模型的Jeffrey RichterC#第20章的CLR book CLR有一個很好的處理:

一旦你完成了它們,你應該把所有的對像都設置為null (VB.NET中Nothing )?

我明白,在.NET中,處理實現IDisposable接口的對象的任何實例都是必要的,以釋放一些資源,儘管該對像在處置後仍然是某些東西(因此表單中的isDisposed屬性),所以我認為它可以仍然駐留在記憶中或至少部分?

我也知道,當一個對象超出範圍時,它會被標記為垃圾收集器的下一個傳遞的收集(儘管這可能需要時間)。

因此,考慮到這一點,將它設置為null加快系統釋放內存的速度,因為它不必解決它不在範圍內,並且它們有任何不良副作用?

MSDN文章從來沒有在例子中做到這一點,目前我這樣做,因為我不能看到傷害。 不過,我遇到了各種意見,所以任何意見都是有用的。







也:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of



一般不需要設置為空。 但是,假設你在課堂上有重置功能。

那麼你可能會這樣做,因為你不想調用兩次配置,因為一些Dispose可能沒有正確實現並拋出System.ObjectDisposed異常。

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }



這種“沒有必要在使用後將對象設置為空”不完全準確。 有些時候你需要在處理完變量後清空它。

是的,當你完成任何事情時,你應該始終調用.Dispose().Close() 。 無論是文件句柄,數據庫連接還是一次性對象。

與此不同的是LazyLoad的非常實用的模式。

假設我已經實例化了class A ObjAClass A有一個名為class B PropB的公共財產。

在內部, PropB使用_B的私有變量,默認為null。 當使用PropB.Get() ,它會檢查_PropB是否為null,如果是,則打開實例化B_PropB所需的資源。 然後它返回_PropB

根據我的經驗,這是一個非常有用的技巧。

在需要null的地方進來的是,如果你重置或者以某種方式改變了A,那麼_PropB的內容就是以前A值的子_PropB ,你將需要Dispose並且_PropB這樣_PropB就可以重置以獲取正確的值如果代碼需要它。

如果只執行_PropB.Dispose()並且在期望_PropB.Dispose()的空檢查成功之後不久,它將不會為空,並且您將查看陳舊的數據。 實際上,您必須在Dispose()之後將其Dispose()才能確定。

我當然希望它是在其他情況下,但我現在有一個代碼,現在在一個_PropB上的Dispose() _PropB並且在執行Dispose的調用函數之外展示了這種行為(並且因此幾乎超出了範圍),私有支持仍然不是't null,陳舊的數據仍然存在。

最終,處置後的財產將被清空,但從我的角度來看,這是非確定性的。

dbkk暗指的核心原因是父容器(帶PropB )將_PropB的實例_PropB在範圍內,儘管Dispose()







一些對象假設強制將資源從內存中移除的.dispose()方法。




Related

c# .net vb.net memory memory-management