2

Dipose()メソッドを持つFTPクラスがあります

public class Ftp : IFtp
    {
        //other methods, properties and fields

        public void Dispose()
        {
            if (_ftp.IsConnected)
                _ftp.Close();

            _ftp.Dispose();
            _ftp = null;
        }
    }

Ftpこれは、クラスにアクセスするために使用しているインターフェイスです

public interface IFtp : IDisposable
    {
        //other methods signatures
        void Dispose();
    }

これは、によって使用されるコンテンツを破棄する適切かつ機能的な方法Ftpですか?

4

3 に答える 3

3

これは、クラスの通常の使用には問題ありません。ただし、_ftpアクセスを開始する前に、参照が null かどうかを確認する必要があります。Dispose一般的な慣行は、害を及ぼすことなくメソッドを複数回呼び出すことができるようにすることです。

クラスを使用するクラスが何らかの理由でそれを適切に破棄できない場合に備えて、クラスにファイナライザーを追加することもできます。

IDisposableインターフェイスのドキュメントにあるコーディング例は非常に完全で、コメントも充実しています。

于 2013-04-14T01:19:40.400 に答える
3

_ftp は IDisposable オブジェクトだと思います。その場合は、次の手順を実行するだけで十分です。

public class Ftp : IFtp
{
    //other methods, properties and fields

    public void Dispose()
    {
        _ftp.Dispose();    
    }
}

また

public interface IFtp : IDisposable
{
    //other methods signatures    
}

つまり、Dispose()インターフェイスが から継承されている場合は、(インターフェイスで) メソッドを再指定する必要はありません。メソッドIDisposableは で既に指定されているためIDisposableです。

于 2013-04-14T01:19:58.897 に答える
2

インターフェイス全般については、MSDN のドキュメントをIDisposable参照してください。

MSDNのIDisposable.Dispose()ドキュメントには、具体的に次のように記載されています。

このメソッドを実装するときは、包含階層を介して呼び出しを伝播することにより、保持されているすべてのリソースが解放されることを確認してください。たとえば、オブジェクト A がオブジェクト B を割り当て、オブジェクト B がオブジェクト C を割り当てる場合、A の Dispose 実装は B で Dispose を呼び出す必要があり、B は C で Dispose を呼び出す必要があります。オブジェクトは、そのベースの Dispose メソッドも呼び出す必要があります。クラスが IDisposable を実装している場合。

...それはあなたがしていることです。

設計上の警告の詳細については、MSDN CA1063: IDisposable を正しく実装する を参照してください。

基礎となる FTP 実装が管理されていないと仮定すると、基本実装にファイナライザーがまだ存在しない場合は、ファイナライザーも含める必要があります。MSDNのIDisposable.Dispose()ドキュメントには、具体的に次のように記載されています。

Dispose メソッドは明示的に呼び出す必要があるため、IDisposable を実装するオブジェクトは、Dispose が呼び出されていないときにリソースの解放を処理するファイナライザーも実装する必要があります。

MSDNObject.FinalizeおよびMSDN Implementing Finalize and Dispose to Clean Up Unmanaged Resourcesも参照してください。

継承チェーンのどこかに適切なファイナライザーがない場合、これが警告の理由でしょうか?

(反例として) Microsoft は、コンシューマーDispose()が直接 呼び出さないことを推奨していることにも注意してください。MSDNusingステートメントのドキュメントには次のように記載されています。

原則として、IDisposable オブジェクトを使用する場合は、using ステートメントで宣言してインスタンス化する必要があります。

コンシューマーに推奨されるアプローチはIDisposable、次のようにリソースを「使用」することです。

   using (FTP myDisposableFTP = new FTP()) {
     ...
   }

これは基本的に「シンタックス シュガー」でありDispose()、使い捨てリソースの使用が終了したとき (つまり、usingブロックの最後)、または重要なことに、ブロック内でusing例外が発生したときにメソッドが呼び出されるようにします。

nullこのパターンでは、インスタンスがブロックの開始時に構築されているため、インスタンス参照のチェックも必要ありません。また、オブジェクトを再割り当てできないようにします (元の参照がスコープ外になった場合でも、基になるリソースが誤って開いたままになるのを防ぎます)。

ただし、このパターン (または同等の try/catch/finally) を継承/インターフェイスの実装に組み込むことができるかどうかは疑わしいと思います。

そうです、Dispose()メソッドを呼び出すことは機能的には問題ありません。必要なすべての状況 (例外処理など) で呼び出すことを忘れない限り、または適切に処理するためにそれを消費者に再公開する場合に限ります。 「ラップされた」IDisposable実装の一部。ただし、リソースが管理されていない場合は、ファイナライザーも追加する必要があります。

于 2013-04-14T01:16:24.867 に答える