2009-07-27 10 views
6

私は、Equalsメソッドを持つコレクションクラスを持っています。これは、各アイテム間の等価チェックを行うメソッドで渡したいものです。C#汎用制約で 'スーパータイプ'の関係を指定できますか?

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection<T> 
{ 
    //... 

    public bool Equals<U>(Collection<T> other, EqualityComparer<U> eq) where T : U 
    { 
     // code using eq delegate to test equality between 
     // members of this and other collection 
    } 
} 

残念ながら、コンパイラは(「Collection.Equals()」「Tを型パラメータを定義していない、この上borks:さらに、私は、デリゲート型はTそのものだけでなく、Tのスーパークラスを操作できるようにしたいです')。このタイプの制約/操作を指定する方法はありますか?

答えて

4

いいえ、私はあなたがそのような制約を指定することはできません。 (私は機会にもそれを望んでいたしました。)

あなたしかし非ジェネリッククラスの2種類のパラメータを持つ静的ジェネリックメソッドを書くことができ

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection 
{ 
    public static Equals<T, U>(Collection<T> first, 
           Collection<T> second, 
           EqualityComparer<U> comparer) where T : U 
    { 

    } 
} 

あなたもその呼び出しを作ることができますジェネリッククラスのインスタンスメソッドあなたが好きなら:

コレクションのインスタンスメソッドがちょうどだろう
// Implementing the static method: 
return first.Equals(second, new EqualityComparer<T>(comparer)); 

public bool Equals(Collection<T> other, EqualityComparer<T> eq) 
{ 
    // ... 
} 

これは、で利用可能な逆変則を使用して、C#2以降の代理人を作成します。

+0

可能なのは意味がありますか? 2つの宣言をプロジェクト全体に広げたり、指定しなくてもいいので、推論では可能にならないでしょうか? – Dykam

+1

はい、それは完璧な意味を持っています。型パラメータを*のサブクラス*にする必要があります他の何か、なぜ他の方法ラウンドですか? (Javaのではなく、 'Tはところで、Foo'を拡張する' TスーパーFoo'を使用して、これを可能にします。) –

+0

ああ - 私はあなたが私がライダーとして書いたものを置くためにあなたの答えを編集していた参照:) – ShuggyCoUk

0

明示的にtypeパラメータをUの継承クラスにする場合は、ジェネリックは必要ありませんが、パラメータの正式な型としてUを使用します。そしてそこにポリモフィズムがキック! :)

1

Jonは、クラスレベルで宣言されているので、制約の範囲内でTを参照することはできないと述べました。あなたは、コレクションのプライベート状態にアクセスすることなくメソッドを書くことができた場合は

(またはそれらの内部である)あなたがそうのように書き換えることができます。

public class Collection<T> 
{ 
    ... 
} 

public static class CollectionExtentions 
{ 
    public static bool Equals<T,U>(
      this Collection<T> first, 
      Collection<T> other, 
      EqualityComparer<U> eq) where T : U 
    { 
      ... // legal to use eq here on the T values with collections 
    } 
} 

をちなみに私はあなたがあなた自身ではなくFunc<T,T,bool>を使用することをお勧め名前付きデリゲート

+0

funcが利用できないので、これは、.NET 2である:( – thecoop

+0

ああ - あなたは質問にそのライダーを追加したい場合がありますダウナーは:((明らかにするので、あなたがそうJonの提案拡張メソッドの構文を使用することはできませんインスタンスメソッドで使用されている静的メソッドの最適です) – ShuggyCoUk

関連する問題