2011-09-15 76 views
9

說我有以下幾點:IDisposable的問題

public abstract class ControlLimitBase : IDisposable 
{ 
} 

public abstract class UpperAlarmLimit : ControlLimitBase 
{ 
} 

public class CdsUpperAlarmLimit : UpperAlarmLimit 
{ 
} 

兩個問題:

1. 我就當我IDisposable的成員實際上被調用有點困惑。當CdsUpperAlarmLimit的實例超出範圍時它們會被調用嗎?

2. 我該如何處理在CdsUpperAlarmLimit類中創建的對象的處理?這也應該來自IDisposable?

回答

22

Dispose()永遠不會自動調用 - 這取決於代碼的實際使用方式。

1)Dispose()當你專門致電Dispose()被稱爲:

myAlarm.Dispose(); 

2)Dispose()被稱爲在使用類的一個實例using塊的結束。

using(var myAlarm = new CdsUpperAlarmLimit()) 
{ 

} 

using塊爲try/finally塊一起Dispose()對象上的呼叫「正在使用」,在最後塊語法糖。

+0

這裏原諒我的無知。我寫了一個實現'IDisposable'的類,當我在'using'塊中使用它時,'Dispose()'方法永遠不會被調用。這是否意味着我仍然需要在''using''塊內部調用Dispose()? – jp2code

+0

@jpcode:不需要 - 'using'塊等價於'finally'代碼塊中帶有Dispose調用的try/finally。 – BrokenGlass

0

使用IDisposable的對象時,它總是很好用這種方式:

using(var disposable = new DisposableObject()) 
{ 
    // do you stuff with disposable 
} 

using塊已運行後,Dispose方法會了IDisposable對象上調用。否則,您需要手動調用Dispose。

3

當我的IDisposable成員實際上被調用時,我有點困惑。當CdsUpperAlarmLimit的實例超出範圍時它們會被調用嗎?

號它當您使用using結構爲得到所謂:

using(var inst = new CdsUpperAlarmLimit()) 
{ 
    //... 
}//<-------- here inst.Dispose() gets called. 

但是,如果你寫這不會被調用:

{ 
    var inst = new CdsUpperAlarmLimit(); 
    //... 
}//<-------- here inst.Dispose() does NOT get called. 

但是,你可以這樣寫以及:

var inst = new CdsUpperAlarmLimit(); 
using(inst) 
{ 
    //... 
}//<-------- here inst.Dispose() gets called. 
0
  1. 當有人打電話給.Dispose就可以了。
  2. 不,它已經通過繼承來實現它。
3

IDisposable有1個成員,Dispose()

當您選擇調用它時會調用它。最典型的情況是,框架使用using塊語法糖爲您完成。

5
  1. 不,IDisposable不會被自動調用。你最好通常呼叫Disposeusing聲明,就像這樣:

    using (ControlLimitBase limit = new UpperAlarmLimit()) 
    { 
        // Code using the limit 
    } 
    

    這實際上是一個try/finally塊,所以Dispose將被稱爲然而你離開塊。

  2. CdsUpperAlarmLimit已經間接實現了IDisposable。如果您按照normal pattern for implementing IDisposable in non-sealed classes,則會覆蓋void Dispose(bool disposing)並在此處處理您的組合資源。

注意,垃圾回收器呼叫Dispose本身 - 雖然它可以調用終結。除非您在非託管資源上有直接句柄,否則應該很少使用終結器。

說實話,我通常覺得值得嘗試改變設計,以避免需要在類中保留非託管資源 - 在一般情況下正確實施IDisposable是坦率的痛苦。如果你的課程是密封的(不需要額外的方法;只需實施Dispose()方法) - 但它仍然意味着你的客戶需要知道它,以便他們可以使用適當的using聲明。

0

當您希望指示您的資源具有必須明確卸載和清理的依賴項時,實施IDisposable。因此,IDisposable永遠不會自動調用(就像垃圾收集一樣)。

一般來說,處理IDisposables,你應該換他們的使用在使用塊

using(var x = new CdsUpperAlarmLimit()) { ... } 

此編譯爲:

CdsUpperAlarmLimit x = null; 
try 
{ 
    x = new CdsUpperAlarmLimit(); 
    ... 
} 
finally 
{ 
    x.Dispose(); 
} 

所以,回到話題,如果你喜歡的類型,CdsUpperAlarmLimit,是實施IDisposable,它對全世界說:「我有必須處置的東西」。這種常見的原因是:

  • CdsUpperAlarmLimit保留其他一些IDisposable的資源(如文件流,ObjectContexts,定時器等),當CdsUpperAlarmLimit完成被使用,它需要確保文件流,ObjectContexts,定時器,等等也得到Dispose調用。
  • CdsUpperAlarmLimit使用非託管資源或內存,並在完成後必須清理或會出現內存泄露