![]() |
Delphi-Version: 5
Beispiel für Attribut an einem Methoden/Funktionsparameter
Der Thread "boolean function: muss result := false gesetzt werden?" brachte mich zu einer älteren Fragestellung zurück:
![]() Die Antwort war Ja (es war nur undokumentiert) und in der Antwort auf Stackoverflow war auch ein Beispiel. Dieses zeigte: RTTI findet das Attribut der Methode. Nun meine Zusatzfrage: wie kann ich den konkreten Wert des Parameters, also zum Aufrufzeitpunkt, ermitteln? Ich vermutete zuerst, dass zum Beispiel in Spring4D etwas in dieser Richtung enthalten ist (leider nein). Ich denke, es wäre ein guter Eintrag für die Codebibliothek. Da ich nun gelegentlich auch in einer neueren Delphi-Version unterwegs bin, würde ich gerne diese kleine Aufgabe lösen:
Beispiel für die Verwendung des Attributs:
Delphi-Quellcode:
procedure TMyClass.OnChangeMe([NotNil] ASender: TObject);
begin // hier ist ASender 'garantiert' nicht nil // ... mache etwas end; |
AW: Beispiel für Attribut an einem Methoden/Funktionsparameter
Bei direktem Aufruf, ist ein gezieltes
Delphi-Quellcode:
oder ein
if Param=nil
Delphi-Quellcode:
garantiert einfacher und vor allem auch "optimaler".
Assert(Assigned(Patem)
Aber z.B. für Schnittstellen, wo Funktionsaufrufe weitergeleitet oder Events mit externen/ungeprüften Parameter aufgerufen werden ... Nja, am Ende wäre auch das die direkte Prüfung einfacher, aber vermutlich in den Zwischenebenen das RTTI auch nutzbar. Wenn der Methoden-Aufruf nicht via RTTI vorgenommen würde und du bereits Deklaration und die Parameter in RTTI-freundlicher Form vorliegen, * mußt du erstmal die Definition der Methode selbst reingeben oder aus der Codeposition versuchen zu finden (bei Events hat du den Typ bereits in der Hand) * und dann die Parameter auch noch bekommen * * mitten im Code nahezu unmöglich ... aber beim / vor dem Aufruf oder als RTTI-Hook im Aufruf ging es aber TRttiProcedureType/TRttiMethodType/TRttiMethod.Invoke oder mit dem TVirtualMethodInterceptor In diesem Fall würde ich dir empfehlen, dieses [NotNil] bzw. ein [Check(...)] als FeatureRequst dem Hersteller zu unterbreiten damit der Compiler automatisiert eine
Delphi-Quellcode:
einfügt, ähnlich wie bei [Weak] , [Volatile] und [Ref] oder den Index- und Überlaufprüfungen durch impliziten zusätzlichen Code.
if Assigned
|
AW: Beispiel für Attribut an einem Methoden/Funktionsparameter
Ich wüsste jetzt nicht, wie man herausbekommt, in welcher Methode man aktuell grade steckt. Wenn man die
Delphi-Quellcode:
kennt, kann man sich da ja weiterhangeln.
TRttiMethod
Eine Möglichkeit wäre ein TVirtualMethodInterceptor der eine bestehende Instanz wrapped und vor/nach jedem Methodenaufruf z.B. die Parameter prüft, verändert, oder was auch immer. Setzt halt nur virtuelle Methoden vorraus und macht das ganze bestimmt nicht schneller als ein hartkodiertes
Delphi-Quellcode:
.
if not Assigned(p) then raise EArgumentNilException
|
AW: Beispiel für Attribut an einem Methoden/Funktionsparameter
Nja, im Prinzip in der Methode, welche kurz vor der aktuellen CodePosition beginnt, aber sicher ist sowas nicht.
Via RTTI alle Klassen+Methoden (nicht normale Prozeduren/Funktionen) durchlaufen und die Adressen vergleichen oder über Debuginfos. Ein __METHOD__, __FUNCTION__, __LINE__ bzw. eigene Preprozessor gibt es ja leider im "Delphi" nicht. ![]() |
AW: Beispiel für Attribut an einem Methoden/Funktionsparameter
Danke für das Feedback - ja, der TVirtualMethodInterceptor ist hier der Lösungsansatz, und ich stimme 100% zu dass ein Assert() auch funktioniert.
Im verlinkten Stackoverflow-Artikel war das Anwendungsbeispiel etwas fortgeschrittener, es sollte ein REST-Request-Parameter extrahiert werden. Durch die Annotation des Parameters mappt man dessen konkreten Wert auf den Anteil des Requests, in dem dieser enthalten ist. Das kann ein Path-, ein Query- oder ein Body-Parameter sein. Dann könnte man Methodensignaturen dieser Art verwenden:
Delphi-Quellcode:
Das würde dann aus der URL z.B. /api/v1/artikel/12345?farbe=blau die Parameter ermitteln und an die Methode weitergeben. Auch hier wäre ein Intercept notwendig, diesmal ausserdem ein Verändern der Parameterwerte, nicht nur ein Lesen.
[GET]
function TMyResource.GetArtikelbestand([PathParam] ArtikelNr: string; [QueryParam] Farbe: string = ''): TArtikelbestandResponse; begin // in ArtikelNr steht nun die aus dem HTTP Request extrahierte Artikelnummer, und in Farbe entsprechend die Artikelfarbe (optional). end; |
AW: Beispiel für Attribut an einem Methoden/Funktionsparameter
Sowas ähnliches geh auch im DataSnap bzw. RADServer von Emba,
welcher ebenfalls eine REST-Schnittstelle bietet. Dazu dann auch noch Dinge ala Benutzerverwaltung/Zugriffsbeschränlungen einzelner Klassen oder Methoden. Wie gesagt, hier wird die Funktion am Ende auf etwas Anderes umgeleitet und über das Framework aufgerufen, wo man vor dem Aufruf dann auch solche Prüfungen machen kann ... vor der Funktion und nicht erst darin. Beim TVirtualMethodInterceptor wird die TypInfo der Klasse geklont, in der abgeleiteten VMT mit den InterceptorCalls die virtuellen Methoden umgeleitet und dann in der Instanz der KlassenZeiger umgebogen. Leider auch bei ALLEN Virtuellen und nicht nur die Gewollten (könnte man aber anschließend selber wieder an der VMT rumfummeln/zurückbiegen). beim Aufruf: Adressen, Register und Stack in TInvokeInfo kopieren intern mehrmals rumreichen und am Ende wieder alles in Register/Stack schreiben und der CALL auf die originle Adresse. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz