Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Dynamischer Methodenaufruf (https://www.delphipraxis.net/196069-dynamischer-methodenaufruf.html)

Ghostwalker 20. Apr 2018 12:56

Dynamischer Methodenaufruf
 
Problem:

Ich möchte eine Liste definieren in der ich bestimmten Schlüsselbegriffen, Methoden eines Objektes zuordnen kann.

Mit Hilfe einer Methode eines anderen Objektes würde ich dann die Methode über den Schlüsselbegriff mit den entsprechenden Parametern (die für jede der definierten Methoden gleich ist) aufrufen.

Was ich damit vermeiden möchte ist sowas:

Delphi-Quellcode:
 begin
   if (key = 'Wert1') then
     DoWert1(param1,param2);
   if (key = 'Wert2') then
     DoWert2(Param1,Param2);
    :
 end;
Mein erster Ansatz war, ein entsprechende Array zu definieren. Dieses dann in einer Schleife durchlaufen
und die Methode über RTTI anhand des Names aufrufen. Aber irgendwie erscheint mir das ein wenig "unelegant".

Hat da jemand vielleicht einen anderen Ansatz ?

Neutral General 20. Apr 2018 12:59

AW: Dynamischer Methodenaufruf
 
Benutz ein TDictionary<string, TDoWertProc> ;)
Delphi-Quellcode:
type
  TDoWertProc = procedure(AParam1: Integer; AParam2: TObject) of object; // Natürlich Parameter anpassen

var doWertDict: TDictionary<string, TDoWertProc>;
begin
  // 1x Initialisieren:
  doWertDict := TDictionary<string, TDoWertProc>.Create;
  doWertDict.Add('Wert1', DoWert1);
  doWertDict.Add('Wert2', DoWert2);

  // Aufruf
  doWertDict[key](param1, param2);
end;

KodeZwerg 20. Apr 2018 19:40

AW: Dynamischer Methodenaufruf
 
Reicht da nicht auch ein normales case aus?

Neutral General 20. Apr 2018 19:51

AW: Dynamischer Methodenaufruf
 
Zitat:

Zitat von KodeZwerg (Beitrag 1400023)
Reicht da nicht auch ein normales case aus?

Ich schätze mal wenn er kein if benutzen will, ist ein case auch nicht so viel besser.
Außerdem funktioniert case nicht mit Strings.
Und ich schätze das Problem ist dass er nicht nur 2 Methoden hat sondern eine ganze Menge und das dann ein recht großer case oder if-Block wäre.

KodeZwerg 20. Apr 2018 20:01

AW: Dynamischer Methodenaufruf
 
Zitat:

Zitat von Neutral General (Beitrag 1400025)
Außerdem funktioniert case nicht mit Strings.

Du hast natürlich mehr als Recht, ist ja kein Ordinaler Typ :thumb::pale:

DeddyH 20. Apr 2018 20:29

AW: Dynamischer Methodenaufruf
 
Nunja, mit einer Array-Konstanten und AnsiIndexText ginge auch case. Allerdings dürfte ein Dictionary performanter sein.

Mavarik 20. Apr 2018 20:36

AW: Dynamischer Methodenaufruf
 
Emm

Delphi-Quellcode:
Var
  CallByName = TDictionary<String,TProc<T,T>>

MichaelT 21. Apr 2018 10:48

AW: Dynamischer Methodenaufruf
 
Der enum erfüllt einen ähnlichen Zweck im Regelfall. Die Wahrnehmung stimmt schon, sowie das Beispiel geschrieben wurde.

Der String selbst ist eine Bag mit in der die Reihenfolge ein Rolle spielt. Im CASE selbst würde eine Stringkonstante geprüft.

Ein Programm kann nicht lernen und liefert bei selben Input immer den selben Output. Das 'Wissen' und die Fähigkeiten des Programms erweiterst du als Programmieren. Sonst ist es kein Programm.

Zwei Beispiele für die Implementierung des Case Statements
Überlegung in Pascal
C/C++

usw ...

Scripts sind keine Programme. Scripting reflektiert eher höhere Änderungsraten. Weswegen du diese eher dynamischeren CASE Konstrukte eher in 4GL und Scripting Umgebungen findest. DB Umfeld.

In Python werden Dictionaries genommen. In C# erfolgt die Umsetzung auch im Dictionary.

Wir machten auf der Uni in Compilerbau noch zwei Implementierungen von CASE und heute wuchert das Thema. (Wenn mit nicht alles täuscht mit Fädelungsliste oder nicht (ob mich richtig erinnere).

--

Wenn du ein Serverprozess jahrelang laufen hast kannst du auch hergehen und die Sprungaddressen nach Aufrufhäufigkeit eher im Vorfeld ansiedeln usw...

Kaum eine Änderung über Jahre ist auch wieder ein anderer Zugang, wobei sich die Änderung einschleicht.

---

Die Realisierung solcher Fragen als 'CASE' oder wie auch immer hängt eben an der Form wie eine Änderung implementiert wird und wie oft. Klarerweise kann Implementierung für die Wahl schöner tauschen. Eine der schnellsten Umsetzung in C# war einmal ein Funktionsaufrauf mit Übergabeparameter ein Character 1:1 mit IFs zurückgemapped auf einen Integer.


Zitat:

Zitat von KodeZwerg (Beitrag 1400026)
Zitat:

Zitat von Neutral General (Beitrag 1400025)
Außerdem funktioniert case nicht mit Strings.

Du hast natürlich mehr als Recht, ist ja kein Ordinaler Typ :thumb::pale:


Ghostwalker 21. Apr 2018 12:38

AW: Dynamischer Methodenaufruf
 
Wie schon vorher gesagt wurde, will ich auf if-Statements verzichten, da das dann in einer Orgie ausarten würde.
Von Übersichtlichkeit und Erweiterbarkeit ganz zu schweigen :)

Da ich als index/key einen String verwende funktioniert auch Case nicht. Und so viel übersichtlicher wird das ganze dann auch nicht.

TDictionary sieht nach dem richtigen Weg aus. So wie der General das beschrieben hat, kann ich mir sogar den ganzen Zirkus mit der RTTI sparen :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz