2009-07-24 18 views
21

複数の汎用制約を追加することが可能かどうか疑問に思っていましたか?C#複数の汎用制約

は、私は、オブジェクト(電子メール、電話またはアドレスのどちらかを)かかりAddメソッドを持っているので、私はのようなものを考えていた:

public void Add<T>(T Obj) 
    where T : Address 
    where T : Email 
    where T : Phone 
{ 
    if (Obj is Address) 
     m_Address.Add(Obj as Address); 
    else if (Obj is Email) 
     m_Email.Add(Obj as Email); 
    else 
     m_Phone.Add(Obj as Phone); 
} 

しかし、私は入れません:

"A constraint clause has already been specified for type parameter 'T'. All of the constraints for a type parameter must be specified in a single where clause."

答えて

25

をあなたはそれをすることはできません。 3つの方法があり、コンパイラがあなたのために苦労しないのはなぜですか?

public void Add(Address address) { m_Address.Add(address); } 
public void Add(Email email) { m_Email.Add(email); } 
public void Add(Phone phone) { m_Phone.Add(phone); } 
+1

だから、どのように他の通常のIEnumerable のような**強く型付けされた汎用コレクション** '異質types'の上で列挙するには? –

+0

@AngshumanAgarwal - 私はこれがコレクションに 'Add'メソッドではないと思っています。 –

+1

もし 'IWalk、IRun、IBothWalkRun'というインターフェースがあるとします。今、IWalk、IRun、およびIBothWalkRunをすべて印刷するように、すべての型から強く型付けされた異種コレクションを作成して繰り返したいのですか?それは意味がありますか? –

1

この場合、とにかくタイプを比較しているので、私は気にしません。これを使用してください:

public void Add(object Obj) 
{ 
    if (Obj is Address) 
     m_Address.Add(Obj as Address); 
    else if (Obj is Email) 
     m_Email.Add(Obj as Email); 
    else if (Obj is Phone) 
     m_Phone.Add(Obj as Phone); 
    else 
     return; 
} 

複数の句がサポートされているとは限りません。あなたはまた別のメソッドオーバーロードを持つこともできます。

5

これら3つのタイプのインタフェースまたは基本クラスを作成することはどうですか?

しかし、あなたのコードを見ると、十分に一般的なものを使用していないようです。ジェネリックの使用のポイントは、あなたがそれを特定のタイプにキャストする必要がないということです(この場合はあなたです)。

9

CLRでは、複数の継承を許可していません。これは、正確に表現しようとしているものです。 TAddressEmailPhone(これらはクラス名であると仮定します)とします。したがって不可能です。もっとイベントは何ですか、この全体の方法は理にかなっていません。あなたは、3つのクラスすべての基本インターフェースを導入するか、Addメソッドの3つのオーバーロードを使用する必要があります。

+9

@Anton、私はOPがOR制約(ANDではない)について質問していると思います。 –

2

この場合、ジェネリック医薬品から実際の利益を得ることはできません。私はちょうど各パラメータタイプの異なるAddメソッドを作成します。

-4

ここで、T:C1、C2、C3。 制約のためにカンマ区切り。基本クラスを使用してみてください。

+4

これは機能しないため、マイナス1 –

0

他の人の話によると、特定のケースでは、ジェネリックではなく継承またはメソッドのオーバーロードを使用する必要があります。ただし、複数の制約を持つジェネリックメソッドを作成する必要がある場合は、このようにすることができます。

public void Foo<T>() where T : Bar, IBaz, new() 
{ 
    // Your code here 
}