2012-01-09 109 views
1

我有幾個靜態方法將窗體轉換爲控件(如下所示)。分析器標記兩個,聲明:「CA2000:Microsoft.Reliability:在方法'...'中,對象'form'不是沿着所有異常路徑處理的。在所有引用之前調用System.IDisposable.Dispose對象'form'超出範圍「。類似的標記爲tabPage代碼分析警告處理表格

注意:對於沒有Enterprise Edition和Analyzer菜單的用戶,這看起來很像FxCop輸出。

我不清楚我應該做什麼。如果new失敗,則會拋出異常。我有什麼機會撥打Dispose

class Foo 
{ 
    static public Form FormAsControl() 
    { 
    Form form = new Foo(); 

    form.TopLevel = false; 
    form.FormBorderStyle = FormBorderStyle.None; 
    form.Dock = DockStyle.Fill; 
    form.Visible = true; 

    return form; 
    } 

    static public TabPage FormAsTabPage() 
    { 
    Form form = Foo.FormAsControl(); 
    TabPage tabPage = new TabPage(); 

    tabPage.Text = form.Text; 
    tabPage.Controls.Add(form); 

    return tabPage; 
    } 

    ... 
} 

回答

6

CA2000麻煩,太多的虛假警告。 FxCop不夠聰明,無法知道Control類是如何工作的。它的Dispose()方法在後創建了一個有用的。只有這樣纔會有可以處置的非託管資源。但是,直到您返回的TabPage被添加到TabControl並且該控件反過來被添加到窗體並調用該窗體的Show()方法之後,纔會發生這種情況。我們看不到的代碼(對於這個問題也沒有FxCop)。此外,他們實際上得到處置,即使有一個例外,當本地窗口被破壞。

您可以通過向方法添加try/catch來禁止警告,以便您可以在catch塊中調用Dispose()。但這是一個錯誤,它只是增加了不必要的代碼,在運行時沒有任何用處。使用[SuppressMessage]屬性擺脫警告。

+0

「[SuppressMessage(」Microsoft.Reliability「,」CA2000「)]」像魅力一樣工作。非常感謝你。 – jww 2012-01-10 18:34:38

1

根據您的代碼,您應該能夠安全地忽略該警告。

0

捕捉異常,調用Dispose,扔?

2

根據你的代碼,不僅應該你忽略了警告,但你必須忽略警告。

一個幼稚的做法是

public Control FormAsControl() 
{ 
    using (Form form = new Foo()) 
    { 
     // Set properties 
     return form; 
    } 
} 

但隨後form將之前調用者可以使用它處理完畢!

請注意,我假設你的意思Foo類從Form派生,而你的意思是FormAsControl返回Control,不Form

+0

同意。謝謝約翰。 – jww 2012-01-10 18:40:02

1

我們可以從這裏C++的RAII技術的東西:

class auto_disposer<C> : IDisposable where C : class 
{ 
    public C Child { get; private set; } 
    public auto_disposer(C c) { Child = c; } 

    public void Dispose() { IDisposable d = Child as IDisposable; if (d != null) d.Dispose(); } 
    public C Release() { C retval = Child; Child = null; return retval; } 
} 

class Foo 
{ 
    static public Form FormAsControl() 
    { 
     using (var ad = new auto_disposer<Foo>(new Foo())) { 
      Form form = ad.Child; 
      form.TopLevel = false; 
      form.FormBorderStyle = FormBorderStyle.None; 
      form.Dock = DockStyle.Fill; 
      form.Visible = true; 

      return ad.Release(); 
     } 
    } 

    // ... 
} 

這樣,如果任何財產分配導致異常,該對象是否仍然適當處理。

相關問題