2013-04-14 103 views
2

我有具有Dipose()方法這是IDisposable的正確用法嗎?

public class Ftp : IFtp 
    { 
     //other methods, properties and fields 

     public void Dispose() 
     { 
      if (_ftp.IsConnected) 
       _ftp.Close(); 

      _ftp.Dispose(); 
      _ftp = null; 
     } 
    } 

這是我使用的用於訪問Ftp

public interface IFtp : IDisposable 
    { 
     //other methods signatures 
     void Dispose(); 
    } 

接口是該用於處置內容的正確和功能的方式FTP類通過Ftp

+0

什麼是_ftp?你能否告訴我們你擔心什麼不工作? –

+0

爲'_ftp'添加null檢查可能是個好主意。 –

+0

'_ftp'是'edtFTPnet'的'FTPConnection'的一個實例,'_ftp'永遠不會爲空。 –

回答

3

我假設_ftp是一個IDisposable對象。如果是的話,它應該是足夠做follwing:

public class Ftp : IFtp 
{ 
    //other methods, properties and fields 

    public void Dispose() 
    { 
     _ftp.Dispose();  
    } 
} 

public interface IFtp : IDisposable 
{ 
    //other methods signatures  
} 

也就是說,你不需要重新指定Dispose()方法(在您的接口),如果你的接口繼承從IDisposable,因爲它已經在IDisposable中指定。

+1

你應該添加密封到課堂上。 –

2

一般請參閱MSDN documentation for IDisposable interface

MSDN IDisposable.Dispose() documentation明確規定:

實現此方法時,確保所有佔用的資源是 通過傳播通過封閉層次的調用釋放。對於 示例,如果對象A分配了對象B,並且對象B分配了對象C,則A的Dispose實現必須調用B上的Dispose, ,必須依次調用C上的Dispose。對象還必須調用 Dispose它的基類的方法,如果基類實現了 IDisposable。

......這就是你在做什麼。

有關您的設計警告的詳細信息,請參閱MSDN CA1063: Implement IDisposable correctly

假設您的底層FTP實施不受管理,您應該應該也包括一個終結器,如果基礎實現中尚不存在。該MSDN IDisposable.Dispose() documentation明確規定:

因爲Dispose方法必須顯式調用,對象是 實現IDisposable還必須實現一個終結處理 釋放資源時,不叫處置。

也可以參考MSDN Object.FinalizeMSDN Implementing Finalize and Dispose to Clean Up Unmanaged Resources

如果有在你的產業鏈沒有合適的終結的地方,也許這是你的警告的原因是什麼?

也請注意(作爲反例)微軟建議消費者不應直接調用Dispose()MSDN using statement documentation狀態:

通常,當您使用IDisposable的對象,還應當聲明並 實例它在一個using語句。

消費者首選的方法是「用」的IDisposable資源,就像這樣:

using (FTP myDisposableFTP = new FTP()) { 
    ... 
    } 

這基本上是「語法糖」,以確保Dispose()方法被調用時,你」重新完成使用你的一次性資源(即using塊的結尾),或者重要的是,如果發生異常using塊。

該模式還避免了對您的實例引用進行null檢查的需求,因爲實例已在該塊的開始處構建。它還確保對象不能被重新分配(即使原始引用超出範圍時也不會保護底層資源不被意外打開)。儘管如此,我認爲你可以將這個模式(或等價的try/catch/finally)合併到你的繼承/接口實現中,這是值得懷疑的。

所以是的,調用Dispose()方法在功能上是OK的,只要你記得在需要它的所有情況下調用它(例如在你的異常處理中),或者你將它重新暴露給你消費者作爲「包裝」IDisposable實施的一部分妥善處理。但是如果您的資源不受管理,您還應該添加終結器。

3

對於班級的正常使用,這很好。但是,在開始訪問它之前,您應該檢查_ftp引用是否爲空。通常的做法是,您應該能夠多次調用Dispose方法而不會造成任何傷害。

您可能還想爲該類添加一個Finalizer,如果使用該類的某個類由於某種原因未能正確處理它,則可以在該類中進行處置。

IDisposable interface文檔中的編碼示例非常完整並且評論良好。

+0

我以爲是這樣,因爲它工作正常,但'Code Analysis'說我應該正確使用'IDisposable'。 「CA1063 \t正確實現IDisposable \t在'Ftp'上提供Dispose(bool)的可覆蓋實現或將該類型標記爲密封。對Dispose(false)的調用應僅清理本地資源。調用Dispose(true)應該清理託管資源和本地資源。「 –

+0

如果您只是封裝另一個實現了IDisposable的類,那麼最終定稿將是不適當的,因爲如果有必要,該類將已經有一個終結器 –

+2

@BrunoKlein,you應該遵循這個指導,希望你可以把你的班級標記爲密封 –