2009-06-10 18 views
4

私は2つのインターフェイス、ジェネリックと継承階層を持っている非ジェネリックを持っている:ジェネリックインターフェイスを実装するすべてのアイテムを列挙するにはどうすればよいですか?

public interface IGenericRelation<TParent, TChild> : IRelation 

public interface IRelation 

一般的なものが動的にロードされているいくつかのサーバーコントロールによって実装され、私はコントロールのコレクションに列挙したいれますこのインターフェイスを実装します。私は、次の

foreach (IRelation relationControl in this.uiPlhControls.Controls.OfType<IRelation) 
    { ... } 

しかし、私が本当に行うことができるようにしたいのですが...

foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation<,>) 
    { ... } 

を行うと、それはとして供給されたタイプでrelationControlを使用することができることができます次に、私は、IGenericRelationで利用可能な強く型付けされたプロパティにアクセスできます。残念ながら、タイプパラメータを省略できないようですので、これは不可能です。

一般的なインターフェイスを実装するコントロールを列挙する方法を知っている人がいますが、私は1つのループではなく複数のループを記述しないようにしていますか?おそらく反射を使用して?

+0

ちょうどこれをした初期のLinqサンプルを覚えているようですが、私がlinqを見に来たときに見つけられませんでした。私はこの空間を見ている。 。 。 –

答えて

3

IGenericRelation<T,F>IGenericRelation<G,I>とは完全に異なるタイプです。これは不可能です。 IGenericRelationに共通する特定のプロパティにアクセスする必要がある場合は、IRelationレイヤに実装するか、またはこれらを実装するIRelationIGenericRelation<,>の間に第3のインターフェイスを導入する必要があります。この理由は、コンパイラには、どの型の実装が期待されるのかを推測する手段がないからです。

これについて移動する最も簡単な方法は、より高いレベル(IRelationまたは中間インターフェースのいずれか)でobjectとしてあなたの2つのプロパティを実装することであると強くIGenericRelation<,>レベルで入力されました。

1

強く入力されているプロパティにアクセスしようとしていますか?それらがジェネリックの入力型であるために強く型付けされている場合は、foreachループで型を指定せずにアクセスすることはできません。それらが強く型付けされているが、ではなく、付属の型に関連するの場合は、それらをIRelationクラスに移動できますか?

これは、コードサンプルでより多くの意味を行います - さんがあなたのクラスのようなものであることを言わせて:あなたのリストはあなたが知らなくても、両方の背中を列挙して得ることができない1 IGenericRelation<Foo, Bar>と1 IGenericRelation<Fizz, Buzz>が含まれていた場合

public IRelation 
{ 
    public string RelationshipType { get; set; } 
} 

public IGenericRelation<TParent, TChild> : IRelation 
{ 
    public TParent Parent { get; set; } 
    public TChild Child { get; set; } 
} 

これはあなたが探している具体的なタイプ:

//Theoretical, non-compiling example.... 
foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation<,>>) 
{ 
    //This wouldn't work for type IGenericRelation<Fizz, Buzz> 
    relationControl.Parent.FooProperty = "Wibble"; 

    //You would be able to access this, but there is no advantage over using IRelation 
    relationControl.RelationshipType = "Wibble"; 
} 

(私も考えられる使用は、いくつかの理にかなっているように、あなたの例のコードからforeachの中relationControlの種類を変更しなければならなかったことに注意してください。)


基本的には、.NETのジェネリックはC++のテンプレートクラスと同じだと思うと便利です(実装は異なるが、この点での効果は同じです)。コンパイル時に、すべてのコードがIGenericRelationクラスの使用について検査され、具体的ではないジェネリッククラスが、TParentキーワードとTChildキーワードの検索を実行し、それらを要求されたタイプに置き換えると仮定します。作成された2つのクラスは他の2つの.NETクラスとは別個であるため、「このテンプレートとして開始したすべてのクラス」を要求するのは意味がありません。この場合は、共有ベースクラスまたはインターフェイスIRelation。

+0

はい、汎用インタフェースの入力タイプです。 –

関連する問題