2012-03-26 10 views
1

私は自分のアプリケーションの中にいくつかのコントロールを持っています。これらのコントロールはすべて明らかにControlクラスを拡張しています。インターフェイスに特定のクラスタイプを適用しますか?

私はいくつかの共有インターフェイスを持つためにこれらのいくつかが必要なので、私は共有機能をカバーするインターフェイスを作成しました。

私のインターフェイスをControlのサブクラスに与えることしかできない方法はありますか?

すなわち、(擬似)

interface IEmbed 

class MyControl1 : Control, IEmbed 

class MyControl2 : Control, IEmbed 

class MyClass : IEmbed 

MyClassのは、それが制御されていなくてもIEmbedを実装しようとするため、理想的には、私は、ここで失敗するようにコンパイラをしたいと思います。

私はこれを間違った方法で行ったのですか、またはこの動作を強制する方法はありますか?

編集

私は、この動作を強制したい、なぜ私が尋ねてきました。

IEmbedの実装を子コントロールとして別の要素に追加する方法があります。

これはすべて正常ですが、Controls.Add()はIEmbedオブジェクトの取得を拒否しますが、これはコンパイルされません。

IEmbedを実装しているものがコントロールでなければならないとコンパイラに伝えたら、それはうまくいくでしょうか?

+0

なぜインタフェースはControlのサブクラスに与えられるべきですか?おそらくあなたはそれをControlにキャストする必要がありますか?そうであれば、単に 'Control GetControl()'と呼ばれるインターフェースにメソッドを追加するだけで、インターフェースがControlのサブクラスではなくても、関連するControlを提供しなければならず、キャストを避けることができます... – digEmAll

+0

編集をご覧ください。 – KingCronus

+0

@digEmAll OPがすべての実装をコントロールにしようとするならば、彼はコントロールをサブクラス化する必要があります(Strilloの答えを参照)。私は特定のGUIフレームワークに何かを結びつけないためにインターフェイスがより良くなると思っていますが、その中の '' Control GetControl() ''メソッドはそれをすべて破ります。 –

答えて

6

いいえ、コンパイル時にこれを強制する方法はありません。

あなたobj is ControlかのIEmbedインスタンスとしてobjを使用する前に、フレームワークのコードのテストを持っていることによって、実行時にそれを強制することができます。

更新:良い解決策は、(この場合は本当に必要はないだろう中間abstract class EmbedControl : Controlを継承し、あなたの方法ではなくIEmbedEmbedControlを受け入れる作ることであろうようなコメントからのフィードバックに基づいて、それが見えます基本クラスのメソッドabstractを使用するだけで、インターフェイスを維持することができます)。

上記のようにうまくいくことがありますが、「基本」クラスから派生する必要がある場合でも、「クライアント」クラスの実装者が独自の中間クラスから派生するように強制するのは望ましくありません。Control同時。この場合は、別の良いアプローチは、ジェネリックを使用することです:

public void DoSomethingWithControl<T>(T control) where T : Control, IEmbed 
+0

私は、問題は、なぜOPがこの動作を強制する必要があるのか​​わからないということです。それを実現する別の方法がおそらくあります。 – digEmAll

+0

私のデザインを再考するつもりです。 – KingCronus

+0

私はIEmbedの実装をとり、それを子コントロールとして別の要素に追加するメソッドを持っています。 これはすべて正常ですが、Controls.Add()はIEmbedオブジェクトの取得を拒否しますが、これはコンパイルされません。 IEmbedを実装しているものがコントロールでなければならないとコンパイラに伝えたら、それはうまくいくでしょうか? – KingCronus

2

私がこのような何かを強制する方法があるとは思わない - しかし、私はあなたが本当にあなただけチェックすることができるように必要とは思いません実行時にインターフェイスのインスタンスがコントロールの場合。

しかし:あなたは、私はあなたがあなたのデザインを見直すことをお勧めしたい、そのようなチェックを実行しないために必要がある場合は

abstract class EmbedControl 
    : Control 
{ 
    // your abstract members 
} 

class MyControl1 : EmbedControl 
5

:alternativleyはだけではなく、インターフェースの(Controlから派生)抽象クラスを使用します。インタフェースは単なる契約であり、それを遵守できるものに制限はありません。タイプが重要な場合は、ベースクラスなどの別のアプローチを試す必要があります。 インターフェイスのメソッドを継承する必要がある抽象クラス(型制約を指定できる)を使用する方法はありますか?

これにより、BaseClassから派生したクラスはすべて、コントロールであり、IInterfaceを実装することが保証されます。

0

宣言を使用せず、チェックTはコントロールですか?

また、私はabaoveに書かれていることに同意します。なぜインターフェイスがタイプであるべきですか?後でコントロールにインターフェイスをキャストすることがわかっている悪いdeszignのように思えます...

0

実際、私は想像できませんが、なぜコントロールが必要ですか?コントロールはIComponentの子孫です。 あなたはそれを継承するべきでしょうか?

0

私が提供しているソリューションは非常に醜いものですが、コンパイル中に失敗します。

public interface IEmbed<T> where T: Control 
{ 
} 

public class A :Control, IEmbed<A> 
{ 
} 

//this fails at compile time as B does not inherit from Control class. 
public class B : IEmbed<B> 
{ 
} 
+0

BはControlを実装していないので、失敗することになります。それは尋ねられる行動です。 – daryal

+0

thxそれは月曜日であり、コード内のコメントを見逃していました。私はコードが一般的にはコンパイルされていないと思った。 – RvdK

+2

これはほとんど良い解決策ではありません。開発者は、 '' T''の目的を知らず、 ''クラスC:IEmbed ''と宣言して、これを簡単に破るかもしれません。 –

関連する問題