Rzutowanie metod
Deti
Nie raz pewnie zdarzyło się, że masz pełno procedur / funkcji w swoich programach i trzeba je uruchamiać w zależności od wywołania. Pokaże tu jak odpalić daną metodę w bardziej dynamiczny sposób.
Najpierw aby zrozumieć co tu robimy - stwórz kilka procedur w swoim programie np.:
procedure MyProc1;
procedure MyProc2;
procedure MyProc3;
Dodaj te zapisy do części interface, a następnie dodaj jakieś przykładowe instrukcje do implementacji. Ale uwaga!: procedury muszą być zadeklarowane w sekcji "published" aby można było na nie rzutować. Gdy już to zrobisz.. - wstaw na przykład na formę button oraz kontrolkę TEdit, niech się nazywają Button1 oraz odpowiednio Edit1. I jeszcze jedna rzecz: wszystkie te 3 procedury są jednego typu ... - dodaj też nowy typ, który będzie odpowiadał tej właśnie budowie metody:
type
TProcedureType = Procedure of Object;
Zrobimy teraz tak, aby po kliknięciu na Button1 wywołała się ta procedura, której nazwa widnieje w naszej kontrolce. Obsługujemy zatem standardowo zdarzenie Button1.OnClick:
procedure TForm1.Button1Click(Sender: TObject);
var
ProcRelay : TProcedureType;
begin
@ProcRelay:= MethodAddress(Edit1.Text);
if @ProcRelay= nil then
ShowMessage('Nie ma takiej metody')
else
ProcRelay;
end;
Jak widać nie jest to specjalnie trudne - najpierw tworzymy sobie zmienną, która będzie wskazywac na naszą metodę. Później przypisujemy jej adres tej metody, którą sobie ktoś wybrał w kontrolce Edit1. Później sprawdzamy, czy w ogóle taka metoda istnieje - jeśli nie to zostaniemy o tym odpowiednio poinformowani :) Jeśli natomiast wszystko pójdzie zgodnie z oczekiwaniami - odpalamy naszą procedurę.
Jak widać sposób ten zaoszczędzi nam nieco zbędnego kodu i wprowadzi trochę zaawansowanego dynamizmu do programu.. :)
Można też zrobić to jako odzielna funkcja, której na wejściu bedzie podawana metoda, a zwracać będzie wartość wartość typu Boolean (True - metoda istnieje, False - metoda nie istnieje) ... przy pierwszej możliwości funkcja ta może oczywiscie daną metodę odpalać.
Również zamiast "Procedure of Object" można dać inny dowolny typ procedury, funkcji...
Witam.
Jak ProcRelay : TProcedureType; przechować w var Event: TNotifyEvent;?
No fajne... ale aby nie pisac za duzo, to wszedzie tam gdzie chce sie wykorzystac wskazniki na funkcje, stosuje sie "funktory"... ot, taki idiom w programowaniu obiektowym. Pozdrawiam.
No fajne... ale aby nie pisac za duzo, to wszedzie tam gdzie chce sie wykorzystac wskazniki na funkcje, stosuje sie "funktory"... ot, taki idiom w programowaniu obiektowym. Pozdrawiam.
Witam.
Dla Milka:
Oto rzutowanie funkcji z parametrem:
Założenie: procedura (lub funkcja) np taka:
Pragnę dodać, iż mimo iż w danej chwili jakiś objekt może mieć dostęp do dwóch metod (np z parametrem lub bez), to MethodAdress jest metodą klasy. Oznacza to, iż pobiera adres metody z typu a nie z objektu(choć z objektu też zadziała). A Dana klasa nie możę mieć dwóch opublikowanych metod o takiej samej nazwie(przeciążonych). Mówiąc inaczej jak dla objektu mamy możliwość przez np form1.procedura wybrać dwie procedury do dostęp i tak mamy tylko do jednej(do tej zadeklarowanej w Typie takim jaki jest form1). Żeby wam jeszcze troche namieszać w głowie to powiem że to idealna metoda aby obejść metody statyczne. Przykład:
Klasa1 ma procedure do;
Klasa2(dziedzicząca od klasa1) definiuje nową procedure do. Obie są statyczne. Teraz mamy objekt: var ob:Klasa1; i potem ob:=TKlasa2.create to wywołując ob.do wywołamy procke z klasa1(bo nie są virtualne). MethodAddress (ale nie z klasy tylko już z ob) mamy dostęp do metody Klasa2.do
Pozdrawiam:)
szkoda troszkę, że poszedłeś na łatwizne :( trzeba było opisać to samo tylko z wykorzystaniem funkcji z parametrem, gdyż częściej występują w programach niż proceduty bez para,etru...
ps. najlepiej jakbyś poprawil
Hmm, może sprawdź, jak VCL to robi, to może się uda?? :) ASM i cierpliwość :)
niezłe, choć osobiście szukam czegoś takiego na typy messejdżów ;] - np. WM_QUIT, WM_SHOW itd. jest jakaś podobna rzecz?
Bardzo dobre! Rzeczywiście wiele kodu i CZASU takie coś pozwala zaoszczędzić... Trafny artykuł!