[delphi] скастить procedure of oject в procedure
В .NET это решается поддержкой делегатов в языке. В C++ можно намутить функторов. Как в Delphi — хз.
просто не охота копипастой заниматься.
Кстати, я тут почитал, оказывается procedure of object — это и есть типа делегат, т.е. она сам объект тоже помнит. Тогда хз почему не преобразуется. А зачем там дописывается TMethod, .Code, напрямую не скастится?
Вот короче:
с принудительным кастом
ForEachRecord(aDataSet, TItrerationTaskOfObject(aPerform;
не компилится:
[Pascal Fatal Error]: F2084 Internal Error: C4989
при попытке обмануть таким образом:
var
tmpMethod: TMethod;
begin
tmpMethod.Code := @aPerform;
ForEachRecord(aDataSet, TItrerationTaskOfObject(tmpMethod;
end;
падает
О, гениальное в своей простоте читерство =)
а у меня связанный с этим читерством вопрос: в делфи что, нельзя создать временный объект? Т.е. там чувак в начале приводит нормальное решение, а потом долго извращается с удалением этого объекта.
чтобы не заботится о памяти в делфи есть 2 подхода к автоматизации применить:
1) наследовать от TComponent:
TGProc = procedure;
TMProc = procedure of object;
class TWGP = class(TComponent)
fgp : TGProc;
constructor Create(AOwner: TComponent; gp: TGProc); override;
procedure ptr;
end;
constructor TWGP.Create(AOwner: TComponent; gp: TGProc);
begin
inherited Create;
fgp := gp;
end;
procedure TWGP.ptr;
begin
fgp;
end;
.....
CallMe(TWGP.Create(SomeObj, GlobalThing).ptr);
тогда оно само сдохнет, когда будет SomeObj дестроится
2) наследовать от TInterfacedObject и повесить на интерфейс:
Iptr = Interface
procedure ptr;
end;
TGProc = procedure;
TMProc = procedure of object;
class TWGP = class(TInterfacedObject, Iptr )
fgp : TGProc;
constructor Create(AOwner: TComponent; gp: TGProc); override;
procedure ptr;
end;
constructor TWGP.Create(AOwner: TComponent; gp: TGProc);
begin
inherited Create;
fgp := gp;
end;
procedure TWGP.ptr;
begin
fgp;
end;
....
CallMe(Iptr(TWGP.Create(GlobalThing.ptr);
тогда тоже сдохнет само, но сразу после завершения выполнения кода.
1ый метод в данном случае вообще ужасен, т.к. TComponent класс не маленький. Второй тоже понимаешь не фонтан, так что автор правильно делает.
Так что, если тебе это позволено, рекомендую.
А сейчас вот возникла необходимость глобальную процедуру туда скормить.
Жаль что с локальной процедурой финт не проходит - она при попытке доступа к локальным переменным процедуры-родителя падает. Хотя конечно можно в параметрах передать нужное, но это неудобно - слишком много где по тексту придётся сигнатуры менять у этой штуки, которую я перегрузил.
Такой вопрос: а шаблонные функции и функция, аргументы у которой - генерики, это одно и то же?
Так эту проблему решает то же самое читерство, параметры сохраняешь в полях того объекта.
З.Ы. только не надо предлагать сохранять в глобальных переменных.
глобальные переменные - зло.
З.Ы. только не надо предлагать сохранять в глобальных переменных.это ты об этом подумал.
глобальные переменные - зло.
Оставить комментарий
kill-still
есть типыTItrerationTask = procedure(aDataSet: TADODataSet);
TItrerationTaskOfObject = procedure (aDataSet: TADODataSet) of object;
как перегрузить процедуру, использующую один из этих типов так, чтобы не писать тело дважды?
procedure ForEachRecord(aDataSet: TADODataSet; aPerform: TItrerationTask);
....
begin
...
aPerform(aDataSet);
...
end;
по идее так:
procedure ForEachRecord(aDataSet: TADODataSet; aPerform: TItrerationTaskOfObject);
begin
ForEachRecord(aDataSet, TItrerationTask(TMethod(aPerform).Code;
end;
но что-то оно падает при касте.
может кто в курсе?