2011-11-24 60 views
1

在抓取通過網絡上的資源,我遇到了很多boiletplate代碼看起來方式如下:處置對象例外

假設我們有一些public class CustomObject: IDisposable,它有一堆的方法。

現在,每個這些方法具有默認健全檢查:

if (inputBuffer == null) 
    throw new ArgumentNullException("inputBuffer"); 
if (outputBuffer == null) 
    throw new ArgumentNullException("outputBuffer"); 
if (inputCount < 0) 
    throw new ArgumentException("inputCount", "< 0"); 

但是(由於IDisposable接口實現)以下檢查被添加到每個方法:

if (disposed) 
    throw new ObjectDisposedException("MethodName"); 

現在 - 這是一種常見的做法嗎?我應該開始重新設計舊的一次性課程並實施這些檢查嗎?

+0

http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.100).aspx見'Dispose'節 – Snowbear

回答

1

這取決於你的用法,如果有疑問,它不會傷害添加它。

對於打算被其他程序(例如庫和框架)使用的類,我會始終執行此檢查並拋出正確的異常,因爲這將有助於其他應用程序診斷錯誤並使類更健壯。

對於僅供我的應用程序使用的內部類,如果在調用方法時錯誤會很快出現,您可以跳過檢查。例如。如果類中的每個方法都使用了一個流,並且該流被置位或設置爲null,則它將很快導致異常。

如果內部類具有不會錯誤的方法,但我會始終使用顯式檢查,因爲我不希望某些方法在對象已被處置後仍然有效(除了方法明確允許它如IsDisposed)。

具有顯式檢查確實具有顯式記錄對象已被處置後允許調用哪些方法的優點。更重要的是,如果您在不調用GuardDisposed的方法的頂部添加註釋以聲明它被允許,則任何不以GuardDisposed開頭的方法或註釋都可能被視爲可疑。

爲了實際執行檢查,我傾向於將其移動到單獨的方法並將其用作斷言(例如斷言)。

public class Foo 
{ 
    private bool disposed; 

    public void DoSomething() 
    { 
     GuardDisposed(); 
    } 

    protected void GuardDisposed() 
    { 
     if (disposed) 
      throw new ObjectDisposedException (GetType().Name); 
    } 
} 
0

您將代碼放入Dispose()(通常爲)方法中,以確保它不會在單個實例上多次明確地(和/或)明確地調用。

當您在該方法中執行一次可以執行的操作(DeleteFile,CloseTransaction ...)以及您可能認爲應該在應用程序域中執行兩次的任何其他操作時。

所以,如果這是一個常見的做法:我會說,這取決於您的應用程序的要求。

2

現在 - 這是一種常見的做法嗎?

是的,建議使用。幾乎所有成員。如果您的類是IDisposable,並且任何需要資源的方法在之後調用Dispose(),則調用代碼中存在嚴重的邏輯錯誤。你的任務是表明這一點。

但請注意,可能有方法(或屬性)不嚴格依賴所擁有的資源,因此在Dispose()之後調用它們可能是安全的。例如一個IsOpen函數/屬性。它可以簡單地返回false,不需要例外。

但是您應該而不是將IsDisposed檢查放入Dispose()iteself中,指南是多次調用Dispose()應該是安全的。

我應該開始重新設計舊的一次性課程並實施這些檢查嗎?

一般來說是個好主意。是否值得這個努力取決於你。

+0

我會表達這些方面:(1)如方法在語義上*對已處理的對象有意義*,它應該對已處理的對象起作用;你的IsOpen示例是一個很好的例子,因爲它可以很合理地回答「不,處置的流不打開」; (2)Dispose的目的是確保任何(仍然)需要在物體可以被放棄之前發生的事情發生;如果什麼都不需要發生,也許是因爲所有必需的事情都已經發生了,那麼情況就已經得到滿足了。 – supercat