2012-01-09 1 views
5

は、WinFormsの設計者はこのようになりますdisposeメソッドを生成します。なぜWinFormsデザイナーは、disposeメソッドで多少「不便」なコードを生成しますか?フォームまたはユーザーコントロールを作成すると

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

このコードの問題は、それが今までに編集された場合、それは間違った行動につながることができるということです追加のオブジェクトを廃棄します。

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
      if (_myDisposable != null) 
       _myDisposable.Dispose(); 
      if (_myOtherDisposable != null) 
       _myOtherDisposable.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

... _myDisposableと_myOtherDisposableの処分は、コンポーネントがnullであるかどうかに依存してはならないとして、間違っていた:私はこのようになり処分方法で.designer.csにファイルを見てきました。

このデザイナで生成されたコードを編集し、テンプレートを編集して変更できるという事実を無視するかどうかについての議論を無視して、私の質問は次のとおりです。これはもっと似ていますか?

protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if(components != null) 
       components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

このコードの最終結果は同じですが、修正中にエラーが発生しにくく、安全です。

+0

第1と第3のコードブロックは(ほとんど)同じです。または私は何かを逃していますか? –

+0

@Erno - '&&'が短絡するので正しいです。 – Oded

+0

質問はありません(スプーン)? –

答えて

4

答えは:あなたの利便性がMicrosoftでこの関数を書いた人の主な関心事ではなかったからです。あるいは、Microsoft以外の従業員であってもプログラマーとしては役に立たないと思っていたかもしれません。そのため、オブジェクトのDispose()メソッドを変更するなどの危険なビジネスから離れるべきです。

ところで、Dispose()メソッドは、 "デザイナーが生成したコードを編集しないでください"と指定された.Designer.csファイル内の領域外にあるため、編集しても問題ありません。

1

あなたはほとんどそうですが、Designer.csファイル内に配置されているという事実については言及していません。

まず、MyForm.csに移動して編集する必要があります。いくつかの常識を持って...

しかし、それは大部分学問です、 コンポーネント== nullは完全に空のフォームでのみ成り立ちます。 1ボタンまたはラベルをドロップしても問題は発生しません。

私がチェックしたのは、空のフォームであっても、nullではありません。 (OK、ちょうどFx 4+のように)

+0

コンポーネントはVS 2010では決してnullではないようですが、VS 2008などでは、Timerなどのコンポーネントをフォームに特別に追加しないかぎり、常にnullになります。 –

1

Formに含まれるリソースの廃棄を処理するための推奨される方法は、FormClosingまたはFormClosedイベントを使用することです。 UserControlには、同じ目的のDisposedイベントがあります。

+0

ClosingおよびClosedはどちらも廃止され、.NET 2.0ではFormClosingおよびFormClosedに置き換えられました。その勧告をどこで見つけましたか? –

+0

@ハンス、私はそれに応じて回答を編集しました。私は口頭で、Closing/Closedを使用するために数年前に言われました。そして、実際にFormClosingとFormClosedという名前が付けられていたことを忘れてしまいました。私は実際には他の名前と時代遅れのイベントがあることを認識していませんでした。 –

3

これは、マイクロソフトの「公式な」IDisposableパターンが不必要に多くの状況に対応しようとしているためです。

詳細については、スティーブン・クレアリーの次の優れた記事を参照してください。What your mother never told you about IDisposable彼はIDisposableの問題に関するいくつかの洞察力を持ち、それらを修正する方法を持っています。

スティーブンは、1つのクラスで管理リソースとアンマネージドリソースを混在させないでください。代わりに、アンマネージリソースを廃棄することを目的とするIDisposableクラスのすべてのアンマネージリソースをラップします。

このガイドラインに従うと、そのような秘密のDisposeメソッドは、Microsoftの推奨パターンで他のより深刻な問題のすべてを解決すると同時に、必要なくなります。

+0

+1。それでも、IDisposableでそれらをラップした後、明示的にまたは 'using(){}'を介して、それらの処理が終わったら 'Dispose()'を呼び出す必要があります。さもなければ、動作はまったくラップされていないよりはるかに優れていません。 – JMD

関連する問題