2016-09-01 15 views
2

of object句で宣言されているDelphi代理人の共通の祖先はありますか?Delphiのオブジェクト代理人の共通の祖先

私はTNotifyEventと私のカスタムデリゲートのための共通の祖先を見つける必要がある:

TMyEvent = procedure(Sender: TObject; msg: stringh); of object; 

これらのイベントを発射するための普遍的な方法を作ること。

ポインタを使用する必要がありますか?またはTObject?

+0

あなたは何をしようとしているのかの例として挙げることができますか?今は、必要なすべてのパラメータを指定せずにメソッドを呼び出すことで、足元で自分を撃っているかのように見えます。 – Johan

+1

私はあなたが 'オブジェクトの手続き(送信者:TObject)'と 'オブジェクトの手続き(送信者:TObject; xyz:TSomehting)'が何らかの形で互換性があるという誤った仮定の下にいると思います。ではない!呼び出し時に正しいシグネチャを持っていない限り、間違ったパラメータが失敗して終了します。 – Johan

+0

私はジェネリックスを使用したソリューションを提案したいと思います。しかし、私は完全な答えを定式化するのに十分な情報がありません。 'TList 'を作成しようとしていますか?それはあなたがしようとしていることですか?もしそうなら、私はその問題に対する簡単な答えを得ました。 – Johan

答えて

6

method pointersの実装の詳細については、ダウンして汚れている必要があります。これらは、いわゆるダブルポインタ値として格納されます。メソッド呼び出しの対象(インスタンス)のための1つのポインタと、メソッド自体(コード)のための1つのポインタ。

SystemのタイプTMethodを使用してメソッドポインタを表すことができます。その宣言は、(簡単にするために取り外さ比較演算子を)ので次のようになります。

type 
    TMethod = record 
    Code, Data: Pointer; 
    end; 

あなたは、これらのタイプの間の割り当てを行うために型キャストを使用する必要があります。

uses 
    System.Classes; 

var 
    Event: TNotifyEvent; 
    Method: TMethod; 

begin 
    Method := TMethod(Event); 
    TMethod(Event) := Method; 
end. 

明らかにこれのどれもが、タイプセーフではありませんあなたは正確さを保証する必要があります。コンパイラはあなたを助けることはできません。チェックポインター型変換演算子asのように、メソッドポインターを処理するものはありません。つまり、TMethodから特定のメソッドのポインタ型にキャストするときは、TMethodインスタンスが実際にキャストするメソッドのポインタ型のインスタンスであることを確認する必要があります。このプロセス全体を、型付きポインタから型なしポインタへのキャストに類似していると考えてください。

TMethodインスタンスに任意のメソッドポインタを格納する場合は、これで問題ありません。しかし、その後、これらのメソッドを起動する必要がある場合はどうなりますか。各TMethodインスタンスの背後にあるメソッドポインタのタイプを知る必要があります。どのようにキャストするのか、どのような議論が必要なのか、それをどのように呼び出すのかを知ることができます。これは、メソッドの真の型について、生のメソッド自体のほかに、余分な情報を格納しなければならないことを意味します。

私は多分、あなたが質問した質問に答えたと思いますが、それはあなたにとって大いに役立つとは思っていません。あなたが達成しようとしていることとあなたが持っている情報についていつもっと知る必要があると思うかを理解するために。

たとえば、メソッドを格納する必要があるときにメソッドに渡す引数が分かっている場合は、変数キャプチャを使用して匿名メソッドでラップすることができます。それはあなたが型安全性を保持し、私が上に示したむしろ疑わしいキャストを避けることができます。おそらくあなたはpartial applicationが必要です。これは、同種のメソッドポインタが同じインタフェースを持つようにするための手段です。この場合も、匿名の方法が役立ちます。

+0

はい、正しいです。 Espは型の安全性の観点から、あなたは前に戻る答えがあると思います。最初にタイプセーフなオプションから始めて、それが失敗した場合にのみ、TMethodタイプのハックを教えてください。 – Johan

+2

多分、私はまだ根本的な問題が何であるかわからないので、実際の質問に集中しました。そして、私はすでにかなりの金額を費やして、それにもっと多くの時間を費やすのは嫌です! –

+0

答えは必要以上の情報を提供します。つまり、TMethodへの型キャストを通してリストに入れ、リストからPMyEvent(listItem)^ PMyEvent =^TMyEventまで呼び出します。 – Paul

関連する問題