2011-09-27 42 views
0

可能重複:
Calling null on a class vs Dispose()優化配置自定義類:設置爲NULL VS .Dispose

只是想關於處置對象的一些信息。

我有創建Employee類這是我從IDISPOSIBLE接口繼承。下面是示例代碼

public class Employee : IDisposable 
{ 
     private Int32 _RunID; 

     public Int32 RunID { get { return _RunID; } set { _RunID = value; } } 

     public void Dispose() 
     { 
      //Dispose(true); 
     } 
} 

現在的問題是,它一個良好的編碼實踐來處置我們每次創建類和執行/與IDisposible接口繼承它,甚至我看到很多其他人的代碼,他們直接設置ObjEmployee = NULL ;所以只是困惑這是好的設置NULL或實現與IDisposible接口或以上沒有?

+4

http://stackoverflow.com/questions/574019/calling-null-on-a-class-vs-dispose ... http://stackoverflow.com/questions/584549/whats-the-point-of -overriding-disposebool-disposing-in-net ... http://stackoverflow.com/questions/12368/how-to-dispose-a-class-in-net ... –

+0

@Tim Schmelter - 你是在暗示這也許可能是重複的? –

+0

@Damien:是的,但首先我想給瑞克看點什麼。 –

回答

5

這取決於,你有管理的資源(文件句柄,套接字連接,等等...),其需要與對象一起被擺脫了?如果是,那麼如果你的類包含基本類型或者只是你不需要處理的信息,那麼你需要一個Dispose(),設置爲null將給GC提示清除該內存。

+1

只有當你看着不會超出範圍的變量時,纔會將它設置爲null。超出範圍的變量,分配給它們的任何對象不再存在於任何範圍內的對象最終都會被GC拾取,因此將這些變量設置爲null將毫無意義,只會浪費您的代碼。 – Sekhat

3

當您設置ObjEmployee = null時,您只會將對象實例標記爲爲垃圾收集器做好準備,但是對實際清理的發生時間沒有影響,並且可能需要一段時間。當您使用Dispose()方法時,GC立即運行並釋放對象正在使用的內存。

+1

調用Dispose()不會觸發GC。 –

2

在決定一個班級是否應該實施IDisposable時,根本問題是該班級的實例是否承擔了查看其他實體得到清理的責任;通常這些其他實體將代表IDisposable對象改變其行爲,並以其他實體爲代價,並且IDisposable對象負責讓他們知道他們何時不再需要這樣做。例如,如果任何地方的任何代碼使用C函數fopen()打開讀寫訪問位於服務器上的文件,則服務器將通過禁止任何其他人訪問該文件來改變其行爲直到它收到關於打開它的程序不再需要它的單詞。當程序不再需要獨佔使用該文件時,它可以調用fclose(),這將導致服務器被通知該文件應該再次可供其他應用程序使用。

如果C#類中的某個方法調用調用fopen()的例程,並且在將FILE *置於C#程序知道但沒有其他事情發生的位置之後,該例程返回,那麼該方法承擔了查看fclose()必須以某種方式被FILE *調用。該文件需要被fclosed(),並且系統中沒有其他任何東西需要這樣做的信息或動力,所以責任歸屬於該C#類。

如果C#方法在沒有將FILE *存儲到任何位置的情況下返回,則文件將永遠不會關閉,除非或直到應用程序退出,否則Universe中的任何人都無法使用它。如果C#方法不必獨佔使用文件而必須退出,它必須以確保在某個地方將不再需要獨佔使用之後清理它的方式存儲FILE *。正常模式是將FILE *存儲在類字段中,對於包含該方法的類,通過複製和消隱該字段來實現IDisposable,看看它是否爲非空白,如果非空白,調用fclose()存儲的FILE *。

要認識到的重要一點是,當一個對象被垃圾收集器銷燬時,系統不會關心任何對象字段中的內容。它甚至不會看他們。重要的是,對象是否有任何未履行的職責,以確保在不再需要其服務時不會被通知的外部實體甚至可能不在同一臺機器上。