2011-07-31 7 views
3

私は自分のプロジェクトについて完全なコード分析を行っていますが、それは500の問題があると言います。私は今300に煮詰めましたが、私は解決策を見つけることができない問題で苦労しています。このシナリオでのコード分析 "CA2000"ルールの解決?

ルールCA2000状態:

ガベージコレクタがのファイナライザを実行したとき、それに対するすべての参照がスコープ外に、オブジェクトはいくつかの不確定時点で配置されますされる前に、使い捨てのオブジェクトは、明示的に配置されていない場合オブジェクト。オブジェクトのファイナライザが実行されないような例外的なイベントが発生する可能性があるため、オブジェクトを明示的に破棄する必要があります。

さらに詳しい情報は、上記のページにあります。ルールがオン故障している

コードは以下です:

internal Window(Game game, Control parent, string title, bool visible) 
    : base(game, parent, visible, new ScreenspaceRectangle(game, Color.Black, Vector.Zero, Vector.Zero)) 
{ 
} 

と説明である:

CA2000:Microsoft.Reliability:方法で「Window.Window(ゲーム、コントロール、文字列、bool) 'の場合、すべての参照がスコープ外になる前に、' ScreenspaceRectangle(game、Color.Black、Vector.Zero、Vector.Zero) 'オブジェクトのSystem.IDisposable.Disposeを呼び出します。

私は、この問題が正常に処理されることを確認するために、作成中のオブジェクトの周りに "using"ステートメントを使用することによって、通常解決できることを理解しています。しかし、私はこの場合どのように解決しますか?

+1

ScreenspaceRectangleを処分する必要があるのはなぜですか? –

答えて

3

Windowクラスはカスタムクラスであると仮定すると、あなたはそれが、コンストラクタの外にそれを必要とし、それがIDisposableを実装し、Dispose方法でScreenspaceRectangleのインスタンスを配置する場合は、基本クラスのコンストラクタはScreenspaceRectangleの参照を格納していることを確認する必要があります。

それ以外の場合は、オブジェクトが基本クラスのコンストラクタに配置されていることを確認します。

1

c#/ vb.netの厄介な制限の1つは、チェーンコンストラクタまたはフィールド初期化子がtry-catchまたはtry-finallyブロックにラップされないことです。オブジェクトFooの作成で、Fooが処理を担当する他のIDisposableオブジェクトを作成する必要がある場合は、Fooのコンストラクタ、そのサブタイプ、またはその例外がスローされた場合にそれらのオブジェクトが確実に破棄されることがありますスーパータイプ。私がこれを処理するために知っているもっともきれいな方法は、 "disposables manager"インスタンスを作成し、それをコンストラクタチェーンに渡すファクトリメソッドでラップされた保護されたコンストラクタを使用することです。 IDisposableを作成するものであれば、それをディスポーザブル・マネージャに追加する必要があります。コンストラクタが例外をスローすると、ディスポーザブル・マネージャは登録されているすべてのディスポーザブルを削除します。

このアプローチの利点の1つは、ネストされたIDisposablesのクリーンアップを作成するコードによって処理できるため、オブジェクト作成とクリーンアップコードが同期しなくなる危険性を最小限に抑えることです。 1つの注意点は、ディスポーザブル・マネージャを追跡するためにスレッド静的フィールドを使用するか、コンストラクタ・チェーンのすべてのステップに渡す必要があることです。前者のアプローチは嫌な感じですが、フィールドイニシャライザがIDisposableオブジェクトを安全に作成できるという利点があります。

関連する問題