2012-01-09 6 views
1

私はフォームをコントロールに変換するいくつかの静的メソッドを持っています(下記参照)。アナライザーは、「CA2000:Microsoft.Reliability:メソッド内で... '」と表明し、オブジェクト'フォーム 'がすべての例外パスに沿って配置されていないことを示します。System.IDisposable.Desposeをオブジェクト'フォーム '範囲外です。 "同様に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もそうである)。さらに、実際にはになります。例外がある場合でも、ネイティブウィンドウが破棄されます。

catchブロックでDispose()を呼び出すことができるように、メソッドにtry/catchを追加することで警告を抑制できます。しかし、それは間違いであり、実行時に役に立たない何もしない不要なコードを追加するだけです。警告を取り除くには、[SuppressMessage]属性を使用します。

+0

"[SuppressMessage(" Microsoft.Reliability "、" CA2000 ")]"チャームのように機能しました。どうもありがとうございました。 – jww

1

コードに基づいて、この警告を無視しても安全です。

0

例外をキャッチしてDisposeを呼び出します。

2

あなたのコードに基づいて、だけでなく、べき警告を無視していますが、警告を無視しなければなりません。

素朴な実装は

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

かもしれないが、発信者がそれを使用する前に、その後formが配置されています!私はあなたを想定してい

Formから派生するクラスFooを意味し、そしてあなたがControl、ないFormを返すようにFormAsControlを意味しています。

+0

ありがとうジョン。 – jww

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(); 
     } 
    } 

    // ... 
} 

この道を。

関連する問題