Delphiの最も一般的な例では、ジェネリッククラスを使用します。 しかし、私のプロジェクトに取り組んで、私はジェネリック型のインターフェースが必要だと決めました。
このプロジェクトでは、組み込みのパブリッシャー/サブスクライバーメカニズムが使用されます。 サブスクライバーに、イベントの種類ごとにアクションを選択する巨大なcase- expressionを持つ個別のメソッドではなく、イベントの種類ごとに個別のReceiveメソッドを持たせたいと考えました。 また、イベントの種類ごとにインターフェイスを定義したくありませんでした。 イベントの種類をパラメーターとして受け取る汎用サブスクライバーインターフェイスが必要でした。
ただし、実装は言うまでもなく、汎用インターフェイスを定義できるかどうかはわかりませんでした。 私がこれを行うことができると仮定しても、Delphiは呼び出す適切なReceiveメソッドを選択できますか? 調べる方法は1つだけです...
注意してください:この例では、コードの一部が削除されており、一般的なインターフェースを示すために必要な部分のみが残っています。 私は次の投稿で他の部分について話します。
最初に、いくつかの簡単なイベントについて説明しました。 彼らのコンテンツはそれほど面白くない:
TSomeEvent = class
// other stuff
end;
TSomeOtherEvent = class
// other stuff
end;
次に、汎用インターフェイスを定義しました
ISubscriber<T> = interface
procedure Receive(Event : T);
end;
このインターフェイスは、さまざまなタイプのイベントを受信するために、サブスクライバーによって実装される必要があります。 イベントのタイプがジェネリックタイプTとして記述されていることに注意してください。
次に、サブスクライバーは、受信したいイベントのタイプごとにインターフェースを実装する必要があります。 これは汎用インターフェイスであるため、非常に簡単です。
TMySubscribingObject = class(TInterfacedObject, ISubscriber<TSomeEvent>, ISubscriber<TSomeOtherEvent>)
protected
procedure Receive(Event : TSomeEvent); overload;
procedure Receive(Event : TSomeOtherEvent); overload;
end;
ISomeEventSubscriberおよびISomeOtherEventSubscriberインターフェイスの説明はありません。ISubscriber<T>を使用して、タイプを所定の場所に渡すだけです。 これを行うには、必ずオーバーロードされたReceiveメソッドを実装する必要があります。
上記のコードは、アイデアの基礎を説明しています。 残りのコードは、対応するテストプロジェクトにあります。 これらの各インターフェイスを実際に定義せずに、それぞれが厳密に型指定されたReceiveイベントを持つ複数のインターフェイスを実装します。
そしてそれは機能しますか? 最初の試行では-いいえ、うまくいきませんでした。 イベントの種類や送信するインターフェイスに関係なく、最後のReceiveメソッドは常に実行されました。
dunit_generic_interfacesライフルール#37:混乱するMalcolmとDelphiコンパイラの開発者のどちらを選ぶかについては、おそらくMalcolmの間違いです。
はい、私の間違い。 バリー・ケリーは私のアプローチの誤りを指摘しました。 一般的なGUIDインターフェイスについて説明しました。 習慣。 これは、 ISubscriber <TSomeEvent>およびISubscriber <TSomeOtherEvent> 、およびこのジェネリックから定義された他のインターフェイスが同じGUIDを持つことを意味します 。 「 as 」演算子を使用してTMySubscribingObjectのインスタンスからリンクを取得すると、Delphiは混乱し、常に同じインターフェイスリンクを返すようになりました。
GUIDと「 as 」を削除しました-すべて正常に機能しました。
今後の投稿では、パブリッシャーとイベントブローカーという他の部分を紹介します。 クラスが興味を持っているイベントを決定することの興味深い副作用は、イベントブローカーがサブスクライバーによって実装されているインターフェイスをチェックして、サブスクライブしているイベントを見つけることができることです。
翻訳の改善にご協力ください。
translate.by/you/generic-interfaces-in-delphi/into-ru/trans
翻訳:©r3code。