2011-01-19 12 views
1

共通の基本型と2つの派生型を持つC#クラス階層があります。私はこのような基本クラス何かの抽象メソッドを宣言します:型は "this"型でなければならないという制約のあるメソッドでは#genericsです。

public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass 

を...と私は、この方法はそれぞれの、Tはその派生型のタイプであるような派生クラスで実装されるようにしたいです派生クラスAの派生型、すなわち、の:

public override IEnumerable<A> GetSiblings<A>() { ... } 

...と派生クラスBで...

public override IEnumerable<B> GetSiblings<B>() { ... } 

別の言い方をするように、各派生クラスはメソッドを実装する必要がありますそれはIを返す同じタイプのアイテムを列挙できます。 C#でこれを実装する方法はありますか?

答えて

0

解決策が見つかりました。明らかにC#4.0では、ジェネリックパラメータ型は共変である可能性があります。 C#3.5以下で動作しません。グーグルが多く集まった。

0

戻り値の型が異なるため、これを行うことはできません。そのような単純な。なぜなら、Aのインスタンスを作成してそれを基底クラスに埋め込む(キャストする)場合、戻り値の型が間違ってしまうからです。

代わりにnewを使用すると、階層が壊れる可能性があります。

0

これは、タイプシステムではサポートされていません。それは、共通の十分な問題だ、

class Animal<T> where T : Animal<T> { } 
class Cat : Animal<Cat> { } // what you desire 
class Dog : Animal<Cat> { } // what is possible yet not desired 

ではなく、まだ適切な関係者(それが誰かわからない、フレームワークプロバイダやC#のチームがあること)の作用を受けてきた問題としてしばしば表現。

費用(および機会費用)と給付によって決定される重要な「価値ある」テストに合格するまでは、それを回避する必要があります。

2

まあ、単一の型のパラメータだけを受け入れるならば、メソッドgenericをほとんど呼び出すことはできず、メソッドのシグネチャには許されない異なる戻り型があります。これらすべてのクラスのインターフェイスを定義して、単にIEnumerable<IMyClass>を返すのはなぜですか?

+0

特定の状況では具体的な型が必要なので、ベース型と派生型で既に実装されているインタフェースは変更できません。 –

+0

'dynamic'の戻り値型を使用できませんでしたか?確かに、コンパイラの最適化は失われますが、いくつかの問題に答えることができ、どのタイプのTでも返すことができます。それに対処するのは消費者の責任です。 – MetalPhoenix

+0

@ MetalPhoenix:あなたは 'object'を返すだけかもしれません... –

関連する問題