クラス A が InterfaceA と IDisposable から継承する場合、InterfaceA が IDisposable から継承する必要があるかどうかを尋ねています。
3 に答える
使用目的によると思います。たとえば、ユーザーが具象クラスをまったく表示せず、インターフェイスのみを表示する場合、ユーザーは実装が を実装することを期待しませんIDisposable
。
ユーザーは次のようなことができます。
var disposable = a as IDisposable;
if (disposable != null)
disposable.Dispose();
しかし、あなたのドキュメンテーションがそうすべきだと明確に述べていない限り、彼らのほとんどはそうしないと思います。
一方、ユーザーが主にクラスを直接操作することを期待している場合、ユーザーはクラスが であることを知っているIDisposable
ため、正しく破棄する可能性が高くなります。
コメントでDIコンテナについて言及しました。これは特定のコンテナーに依存しますが、ほとんどの DI コンテナーは、オブジェクトが使用されなくなったことを知ったときにオブジェクトを破棄すると思います。ただし、これは、コンテナがオブジェクトが使用されなくなったことを認識しており (Castle の場合、これはおそらく を呼び出すことを意味しRelease()
ます)、「シングルトン ライフスタイル」(Castle の用語で) を使用しないことを前提としています。
実装してクリーンアップを必要とするオブジェクトインスタンスへの参照を保持する最後のエンティティが、そのインスタンスを としてのみ認識し、その基になる型として認識しない可能性が高い場合、インターフェイスIFoo
はおそらく実装する必要があります。IDisposable
IFoo
IFoo
たとえば、implements の理由IEnumerator<T>
はIDisposable
、クリーンアップが必要な実装はごくわずかですが、インスタンスは通常、 を呼び出すコードによって作成されるためですIEnumerable<T>.GetEnumerator()
。このようなコードは、多くの場合、返されるオブジェクトの実際の型についてまったく手がかりがありませんGetEnumerator()
。結果として、返されたオブジェクトがクリーンアップを必要とするかどうかを知る方法がありません。クリーンアップが必要な列挙子を破棄しないと悪い結果が生じる可能性があるため、唯一の安全な仮定は、不明な型の列挙子は可能であればクリーンアップする必要があるということです。
非ジェネリックIEnumerator
は を実装IDisposable
していませんが、それはクリーンアップが必要ないという意味ではありません。むしろ、呼び出すコードは、IEnumerable.GetEnumerator()
返されたオブジェクトが実装されているかどうかを確認しIDisposable
、実装している場合はそれを確認する必要があることを意味しますDispose
。これはかなり遅くて面倒です。IEnumerator
実装されている場合、クラスのクリーンアップが必要かどうかにかかわらずIDisposable
、コードは単純に呼び出すことができます。Dispose
何もしない場合でもDispose
、実装されていることがわかっているインターフェイスで何もしないルーチンを呼び出すと、実装されていないインターフェイスをテストするよりも無駄な時間が短くなります。
if の処理が必要な実装はほとんどありませんが、 mustの不明な実装IEnumerator
を呼び出すすべてのコードは、正確を期すために へのキャストを試みることに注意することが重要です。がを実装するという事実は、を呼び出すコードの義務を追加しません。むしろ、そのような義務を明確にし、それらを遵守するためのコストを削減します。GetEnumerator
IEnumerable
IDisposable
IEnumerable<T>
IEnumerable
IDisposable
IEnumerable<T>
いいえ。
実装クラスが を継承しているからIDisposable
といって、そのインターフェイスが を実装する必要があるわけではありませんIDisposable
。
IDisposable
クラスが管理されていないリソースを解放する方法として使用することを意図しています。あなたのインターフェースが管理されていないリソースを使用するために実装クラスを必要としない可能性は十分にあります。そのため、実装で を実装する理由はありませんIDisposable
。