6

私は「学習プログラム」に取り組んでおり、学習に Code Rush リファクタリング ツールを使用しています。Code Rush の最新の更新では、私のプログラムに IDisposable を実装することが推奨されています。IDisposable について MSDN が何を言っているかは知っていますし、それが何をするかについての基本的な理解もありますが、それを実装することのすべての意味を知らないので、推奨事項を無視してきました。今日、私はそれについてもっと学ぶことに決め、推奨事項に沿って進みました.

これが私のプログラムに追加されたものです。

class Program : IDisposable
{
    static Service _proxy;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            if (_proxy != null)
            {
                _proxy.Dispose();
                _proxy = null;
            }
    }

    ~Program()
    {
        Dispose(false);
    }

だから私の質問はこれです。IDisposable の利点を得るために必要なすべてのことを行う必要がありますか、それとも機能させるためにコードで何かを行う必要がありますか? それにブレークポイントを設定しましたが、デバッガーを介して到達しなかったため、必要なかったか、意図したとおりに使用していません。誰かがこれが私のために何をしているのか、またはそれをどのように使用する必要があるのか​​ に光を当てることができますか?

4

2 に答える 2

10

この場合、は、クラスがリソースをカプセル化するためCodeRushに実装することを提案しています(静的であるため、これは完全に良いことではありませんが、表示されます)。Code Rushは、使用しているタイプが明示的にクリーンアップされるべきであると考えていますが、クラスを介してそれを行う方法を提供していません。IDisposableIDisposable_proxy

そうは言っても、IDisposable注意が必要です。これは、生成されたコードが(_proxyインスタンス変数であっても)実際には適切な実装ではない場合の1つです。この場合、デストラクタを使用しないことをお勧めします。これはGCでパフォーマンスの問題を引き起こしますが、この場合、カプセル化されたリソースが呼び出しを忘れた場合に処理する必要があるため、安全性には役立ちませんDispose()。詳細については、IDisposableに関する私のシリーズ、特にIDisposableクラスのカプセル化を参照してください。

さらに、リソースがであるため、上記のコードでは、このクラスを実装しないでくださいIDisposable(他に理由がない限り)。インスタンスから静的リソースを破棄すると、少なくとも一般的なケースでは問題が発生する可能性があります。(この場合、明らかに問題はありませんが、良い習慣ではありません...)通常、静的変数の有効期間はインスタンスメンバーとは大きく異なるため、自動的に破棄することは不適切です。_proxystatic

于 2011-12-05T22:18:10.000 に答える
0

適切に作成されたプログラムでは、任意の時点で、IDisposable の意味のある実装を持つ可能性のあるすべてのオブジェクトに対して、IDisposable.Dispose が最後の "そのインスタンスの実際の使用」とその最終的な放棄。一般に、オブジェクト Foo が IDisposable を実装するオブジェクトへの参照を保持する場合は、次のシナリオの少なくとも 1 つを適用する必要があります。

  1. 他のオブジェクトも、少なくとも Foo がそれを必要とする限り参照を保持し、それに対する Dispose の呼び出しを処理するため、Foo は他のオブジェクトに Dispose を処理させる必要があります。
  2. 参照を保持しているオブジェクトは、問題の IDisposable オブジェクトを最後に使用します。Foo が Dispose を呼び出さない場合は、他に何も呼び出されません。そのシナリオでは、Foo は、他のオブジェクト (Foo) が不要になった後、破棄される前に、他のオブジェクトの Dispose メソッドが呼び出されるようにする必要があります。これを処理する最も慣用的な方法は、Foo が IDisposable.Dispose を実装し、その Dispose メソッドが最後の有用な参照を保持する IDisposable オブジェクトで Dispose を呼び出すことです。

クラス デザイナーが、そのクラスが IDisposable オブジェクトへの最後の有用な参照を保持するかどうかを判断できないシナリオがいくつかあります。場合によっては、コンストラクターに渡された IDisposable が「貸し出される」か「与えられる」かをクラス コンストラクターに指定させることで、この問題を解決できる場合があります。他のケースでは、参照カウント ラッパーまたはその他の複雑な手法の使用が必要になる場合があります。

于 2011-12-06T00:55:59.940 に答える