必要なのは、デリゲートではなく、インターフェイスタイプのようです。デリゲートは受け入れられませんが、インターフェースメソッドはオープンジェネリック型(あなたが求めているもの)を受け入れることができます。たとえば、次のように定義できます。
interface ActOnConstrainedThing<CT1,CT2>
{
void Act<MainType>(MainType param) where MainType: CT1,CT2;
}
CT1
との実装者がとを実装CT2
する共通のベースタイプを共有しない場合でも、の実装はCT1
、CT2
渡さAct
れたパラメーターを型キャストとして、CT1
または型キャストなしで使用でき、制約付きCT2
の汎用パラメーターを期待するルーチンに渡すこともできます。そのようなことは、代表者では不可能です。CT1
CT2
デリゲートではなくインターフェースを使用するということは、通常の「イベント」メカニズムと構文を使用できないことを意味することに注意してください。代わりに、イベントパブリッシャーとなるオブジェクトは、目的のインターフェイス(aList<ActOnConstrainedThing<IThis,IThat>>
など)を実装するオブジェクトインスタンスのリストを維持し、そのリストのインスタンスを列挙する必要があります(おそらくを使用してforeeach
)。例えば:
List <IActOnConstrainedThing <IThis、IThat >> _ActOnThingSubscribers;
void ActOnThings <T>(T param)ここで、T:IThis、IThat
{{
foreach(_ActOnThingSubscribersのvarthing)
{{
things.Act <T>(param);
}
}
編集/補遺
私がこのパターンを採用した場所には、質問にあまり関連していないように見える他のいくつかのものもありました。私の解釈では、オープンタイプのパラメーターを持つデリゲート(または同等のもの)をどのように持つことができるかを尋ねていたので、オブジェクトはデリゲートと同等のものは、デリゲートを提供するオブジェクトが事前にそれを知る必要なしに、タイプパラメータを提供できます。これが役立つほとんどの場合、一般的な制約が含まれますが、それは明らかに混乱を招いたため、次のような例はありません。
インターフェイスIShuffleFiveThings
{{
void Shuffle <T>(ref T p1、ref T p2、ref T p3、ref T p4、ref T p5);
}
List <IShuffleFiveThings _ShuffleSubscribers;
void ApplyShuffles <T>(ref T p1、ref T p2、ref T p3、ref T p4、ref T p5)
{{
foreach(_ShuffleSubscribersのvar shuffler)
{{
things.Shuffle(ref p1、ref p2、ref p3、ref p4、ref p5);
}
}
このIShuffleFiveThings.Shuffle<T>
メソッドは、5つのパラメーターを受け取り、それらを使用ref
して何かを実行します(おそらく、何らかの方法でパラメーターを並べ替えます。ランダムに並べ替えるか、ランダムに並べ替えて、他のパラメーターをそのままにします。リストがある場合IShuffleFiveThings
、そのリストにあるものは次のようになります。ボクシングやリフレクションを使用せずに、あらゆる種類のもの(クラス型と値型の両方を含む)を操作するために効率的に使用されます。対照的に、デリゲートを使用する場合は次のようになります。
void ActOn5RefParameters(ref p1、ref p2、ref p3、ref p4、ref p5);を委任します。
次に、特定のデリゲートインスタンスは、作成時に指定された単一のパラメータタイプにのみ作用できるため(リフレクションを介してのみ呼び出されるオープンデリゲートでない限り)、必要なオブジェクトのタイプごとにデリゲートの個別のリストを作成する必要があります。シャッフル(はい、通常は整数インデックスの配列を使用して順列を処理することを知っています。順列を操作として選択したのは、すべてのオブジェクトタイプに適用できるためであり、この特定の順列方法が役立つためではありません)。
タイプインには制約がないため、実装は型キャスト(ボクシングを導入する可能性があります)を除いて、タイプT
インで多くのことを実行できないことに注意してください。IShuffleFiveThings
このようなパラメータに制約を追加すると、それらがはるかに便利になります。インターフェイス内でそのような制約をハードコーディングすることは可能ですが、それはインターフェイスの有用性をそれらの特定の制約を必要とするアプリケーションに制限します。制約自体を一般的なものにすることで、その制限を回避できます。