Вам необходимо спуститься и загрязниться деталями реализации для method pointers. Они хранятся в виде так называемого двойного указателя. Один указатель на объект вызова метода (экземпляр) и один указатель на сам метод (код).
Вы можете использовать тип TMethod
от блока System
для представления указателей методов. Его заявление выглядит так (с операторами сравнения удалена для простоты):
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, как средство адаптации ваших неоднородных указателей методов к одному и тому же интерфейсу. В этом случае снова могут помочь анонимные методы.
Можете ли вы привести пример того, что вы пытаетесь сделать. Сейчас кажется, что вы пытаетесь стрелять в ногу, вызывая методы, не поставляя все необходимые параметры. – Johan
Я думаю, что вы ошибаетесь, полагая, что 'процедура (отправитель: TObject) объекта' и' procedure (Sender: TObject; xyz: TSomehting) объекта' каким-то образом совместима. Они не! Если у вас нет правильной подписи при вызове, вы передадите неправильные параметры, заканчивающиеся неудачей. – Johan
Я хотел бы предложить решение с использованием дженериков. Но у меня недостаточно информации, чтобы сформулировать полный ответ. Вы пытаетесь сделать «TList», который вы можете вызвать; это то, что вы пытаетесь сделать? Если это так, у меня есть легкий ответ на эту проблему. –
Johan