2010-10-08 17 views
4

我一直在寫一些自定義的WinForm控件,它會執行相當多的繪圖工作,因此往往會有很多一次性的基於圖形的字段(畫筆,鋼筆,位圖等),因此我的控件的Dispose ()方法必須在每個方法上調用Dispose。自動處置擴展方法是否合理?

我擔心我(或未來的維護者)可能很容易錯過需要處理的字段,可以通過忘記Dispose或未意識到它實現了IDisposable。因此我寫了一篇關於對象的一個​​非常簡單的擴展方法,找到所有了IDisposable領域,他們的處理方式:

static public void DisposeAll(this Object obj) 
{ 
    var disposable = obj.GetType() 
         .GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) 
         .Select(fi => fi.GetValue(obj)) 
         .Where(o => o != null && o is IDisposable) 
         .Cast<IDisposable>(); 

    foreach (var d in disposable) d.Dispose(); 
} 

我的問題基本上是這是否是做一個合理的事情。我想不出它會搞砸了什麼,但是我對WinForms的內部工作並不是特別熟悉,這看起來就像是一種可能會引起惱人的錯誤的東西(與反射和處置有關)。

+0

您可以使用'.OfType ()'替換'Where'和'Cast'調用。 – SLaks 2010-10-08 13:30:23

+0

謝謝。 OfType擴展是否也檢查空值?我會假設沒有。 – Gibsnag 2010-10-08 13:44:12

回答

4

通常你不想處置所有的一次性成員。例如。對父表單的引用。

0

我覺得這很危險。如果你實現這個想法,那麼對象將被丟棄(如果它是一次性的),並且在某些情況下,比如當你需要該對象存在時,它將會消失。

自動化對於您確定不會被退回的對象來說是很好的選擇。

1

很難說它是否適合您的特殊情況;我發現Dispose()調用的順序最大。如果一個非託管手柄取決於另一個,你將有一個奇怪的問題與繪圖,內存等

恕我直言。

2

不,這不是一個好方法。您在OnPaint方法中創建的圖形對象應始終爲局部變量,使用語句包裝在中。你的方法需要聲明一個類,只是爲了存儲這些對象。痛苦和低效。此外,你將處置不應該丟棄的對象。像預製筆和畫筆一樣,Pens.Black例如。