2012-06-25 1 views
16

私たちは、このようなジェネリック型パラメータの制約「由来」指定することができます。"どこから派生したものではない"という一般的な型制約がありますか?

class Bar<T> where T : IFooGenerator 

が由来ませを指定する方法はありますか?


私のユースケース:私はそれぞれに同じ並列化コードで、並列化されているFooGenerator Sの束を持っているが、我々は並列化され常ににそれらをしたくありません。

public class FooGenerator : IFooGenerator 
{ 
    public Foo GenerateFoo() { ... } 
} 

したがって、私は並列ではFooを生成するための汎用コンテナクラスを作成します。

public class ParallelFooGenerator<T> : IFooGenerator where T : IFooGenerator 
{ 
    public Foo GenerateFoo() 
    { 
     //Call T.GenerateFoo() a bunch in parallel 
    } 
} 

私はFooGeneratorParallelFooGenerator<FooGenerator>を交換可能にしたいので、私はParallelFooGenerator : IFooGeneratorを作ります。しかし、私は明らかにParallelFooGenerator<ParallelFooGenerator>を合法的にしたくありません。

補助的な質問として、「派生していない」制約が不可能な場合、これを設計する方が良いでしょうか? ParallelFooGeneratorは総称型であり、汎用引数を指定していないため、

+2

'' ParallelFooGenerator'がジェネリック型であり、あなたが一般的な引数を指定しなかったので、ParallelFooGenerator は 'まだ、できません。例えば、 'ParallelFooGenerator >'が可能です - 本当にそのような型を許すのでしょうか? – cdhowie

+1

いいえ、それは不可能です - 許可された制約:http://msdn.microsoft.com/en-us/library/d5x73970.aspx – Slugart

+0

@cdhowie:うわー、ダルプ、そうです。まあ、それは私の問題を解決する:)しかし、問題はまだ他の人に役立つことができます! –

答えて

9

あなたは、次のようなものを使用することができます

public interface IFooGenerator 
{ 
    Foo GenerateFoo(); 
} 

interface ISerialFooGenerator : IFooGenerator { } 

interface IParallelFooGenerator : IFooGenerator { } 

public class FooGenerator : ISerialFooGenerator 
{ 
    public Foo GenerateFoo() 
    { 
     //TODO 
     return null; 
    } 
} 

public class ParallelFooGenerator<T> : IParallelFooGenerator 
    where T : ISerialFooGenerator, new() 
{ 
    public Foo GenerateFoo() 
    { 
     //TODO 
     return null; 
    } 
} 
+1

これはより良いデザインimhoです。*継承を1レベル下に制限するのではなく、1レベル上のインターフェイスを追加することは、より洗練された理解しやすい方法です。各インタフェースとクラスは、それぞれ独自の意味を持ちます。 – vidstige

+0

@cdhowieは* my *の問題を解決しましたが、タイトルの質問に答えるので、これを正しくマークしています。ありがとう! –

7

ParallelFooGenerator<ParallelFooGenerator>が既に使用できません。

たとえば、ParallelFooGenerator<ParallelFooGenerator<SomeFooGenerator>>が可能です。このようなタイプは本当に悪いですか?

4

簡単な答えはノーです。

長い答え(まだ):

Microsoftはそのexplanation of type constrainsでうまくそれを置く:「コンパイラは、それが呼び出す必要があるオペレータや方法があるかもしれない任意の型引数によりサポートされることを、いくつかの保証を持っている必要がありますクライアントコードで指定されています。

制約の基本的な目的は、特定の型の使用を禁止するのではなく、コンパイラがどの演算子またはメソッドがサポートされているかを知ることができるようにすることです。ただし、実行時にcheck if a type implements/inherits a specific interface/base classを実行して例外をスローすることができます。しかし、それでインテリセンスからの設計時間エラーを得ることはできません。

こちらがお役に立てば幸いです。

関連する問題