2009-05-30 8 views
6

Similar question but not quite the same thingC#のインターフェイスで拡張メソッドを使用した疑似多重継承?

私はインタフェースと同じ名前空間の拡張メソッドを使用すると、重複したコードと同じインタフェース10で同じよ​​うに実装を持つ必要がないという点で多重継承と同様の効果を得ることができると考えていました異なるクラス。

これにはいくつかの欠点がありますか?私はプロがかなり明白であると思う、それは後であなたを後で噛ませるために通常戻ってくる問題である。

私が見ている欠点の1つは、拡張メソッドを仮想にすることができないということです。そのため、実際にすべてのインスタンスに対して同じ方法を実装する必要があります。

答えて

4

拡張メソッドを使用してインターフェイス機能を構築する際に表示される問題は、もはやインターフェイスを実際に実装していないため、オブジェクトをインターフェイスタイプとして使用できないことです。

私はIBar型のオブジェクトを受け取るメソッドがあります。拡張メソッドを使用してFooクラスのIBarインターフェースを実装すると、FooはIBarから派生するものではなく、互換性をもって使用することができません(Liskov Substitutionの原理)。確かに、私はFooに追加したい振る舞いを得ていますが、最初にインターフェイスを作成する上で最も重要な面を失います。抽象的な契約を定義することができ、さまざまなクラスによってさまざまな方法で実装できます依存クラスは具体的な実装について知る必要はありません。

もし私が多重継承を必要としていたのですが(これまで私はそれなしで暮らしていました)、コードの重複を最小限に抑えるために代わりに合成を使用すると思います。拡張メソッドはオブジェクトへを行って何かしている間

+0

「FooはIBarから派生したものではなく、互換性がない」と説明できますか? パブリッククラスFoo:IBarを使用している場合、IBarが期待される場所にFooを渡すことはできません。それとも違う意味ですか? 私はそれがインターフェイスとして機能しなくなることを認識します。機能的には、インタフェースよりも仮想メソッドを持たない具体的な基底クラスのように機能します。(良いアイデアであろうとなかろうと別の質問かもしれませんが、DRYを維持することは有益です) – Davy8

+0

ほとんどの場合、私は多重継承の必要性はあまり感じませんが、文字通り同じコードを持つ10-20個の異なるクラスで同じインターフェースを実装している場所で繰り返しコードが繰り返されているようで、メソッドを持つ別の基底クラスからすでに派生しているため、基本クラスに入れることはできません別のインターフェイスに共通です。 – Davy8

+0

FooがIBarから派生する場合は、IBarを実装する拡張メソッドではなく、インスタンスメソッドが必要です。これらのメソッドを拡張メソッドに委譲する予定ですか?私は実装が拡張機能によってのみ提供されていると仮定していました。委任を行っている場合は、希望のインターフェイス機能を実装する基本クラスからの構成が拡張メソッドよりも望ましいと思います。おそらく、デコレータパターンを使用して機能を提供することができます。 – tvanfosson

1

これについて考えるまともな方法は、インスタンスメソッドがオブジェクトによってを行って何かしていることです。フレームワーク設計ガイドラインでは、可能な限りインスタンスメソッドを実装する必要があると私はかなり確信しています。

インターフェイスでは「この機能の使用については気にかけていますが、どのように達成されているかはわかりません」と宣言しています。これにより、実装者は方法を自由に選ぶことができます。それは、インテント、つまりパブリックAPIを、メカニズム、具体的なコードを持つクラスから切り離します。

これがインターフェイスの主な利点であるため、拡張メソッドとして完全に実装することは、その目的を破るようです。さらにIEnumerable<T>にはインスタンスメソッドがあります。

を編集します。オブジェクトは、含まれているデータに基づいて処理されます。拡張メソッドは、オブジェクトのパブリックAPIのみを見ることができます(静的メソッドなので)。オブジェクトの状態をすべて公開して機能させる必要があります(OOのno-no)。

+0

私は多分質問をひどく言いましたが、私は基本的にそれをインターフェースとして扱わないことを意味しています。インタフェースは、コードを再利用し、それをサポートしない言語で貧困者の多重継承を実装するというタスクを達成するための技術的手段にすぎません。 – Davy8

+0

あなたが何を求めているかわかります。最終的には、インターフェイスを実装することで「オプトイン」するクラスに動作を追加することができます。複数のインタフェース=複数の動作=複数の継承。良い推論ですが、それはどういう意味ですか?拡張メソッドがそのオブジェクトの状態を操作できるように、オブジェクトの状態を公開する必要があります。しかし、誰もがその状態を見ることができるので、カプセル化はありません。それでも、このメソッドはメンバを持たないIBarのみを取得するため、あまり役に立ちません。拡張メソッドは何をすることができますか? @ tvanfossonは言ったように、構成はあなたの最善の策です。 –